Created
December 30, 2022 18:24
-
-
Save TerrorJack/94841d52157f4912bc669ed9cea4f639 to your computer and use it in GitHub Desktop.
Unpacked Maybe type in Haskell
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Maybe | |
main :: IO () | |
main = do | |
print $ myJust "23333" | |
print (myNothing :: MyMaybe ()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- | Unpacked 'Maybe' type by @TerrorJack. Tested with -O0 and ghci | |
-- -fobject-code in GHC-9.4.4. Heavily inspired by | |
-- https://twitter.com/AndreasK_Tweets/status/1545112873290153991, | |
-- with a improvement: Laziness is preserved when calling the 'myJust' | |
-- smart constructor. The thunk is only forced when calling 'isJust' | |
-- (we have to, since 'MyMaybe' is lifted and may be a thunk that | |
-- evaluates to 'myNothing' in the end). | |
{-# LANGUAGE BangPatterns #-} | |
{-# LANGUAGE MagicHash #-} | |
{-# LANGUAGE GHCForeignImportPrim #-} | |
{-# LANGUAGE UnliftedFFITypes #-} | |
module Maybe | |
( MyMaybe, | |
myJust, | |
myNothing, | |
isJust, | |
fromJust, | |
) | |
where | |
import GHC.Exts | |
newtype MyMaybe a = MyMaybe {fromJust :: a} | |
instance Show a => Show (MyMaybe a) where | |
show v | |
| isJust v = "Just " <> show (fromJust v) | |
| otherwise = "Nothing" | |
myJust :: a -> MyMaybe a | |
myJust = MyMaybe | |
myNothing :: MyMaybe a | |
myNothing = unsafeCoerce# nothing# | |
isJust :: MyMaybe a -> Bool | |
isJust !v = case isJust# (unsafeCoerce# v) of | |
0# -> False | |
_ -> True | |
foreign import prim "stg_Nothingzh" nothing# :: Any | |
foreign import prim "stg_isJustzh" isJust# :: Any -> Int# |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "Cmm.h" | |
import CLOSURE stg_dummy_ret_closure; | |
stg_Nothingzh () { | |
return (stg_dummy_ret_closure); | |
} | |
stg_isJustzh (P_ val) { | |
if (val == stg_dummy_ret_closure) { | |
return (0); | |
} else { | |
return (1); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment