假设我有
data Foo p =
NoFoo
| YesFoo (forall a. p a)
Run Code Online (Sandbox Code Playgroud)
我可以写
fromFoo :: Foo p -> Maybe (p a)
fromFoo NoFoo = Nothing
fromFoo (YesFoo p) = Just p
Run Code Online (Sandbox Code Playgroud)
它也可以走另一条路:
toFoo :: forall p.
(forall a. Maybe (p a))
-> Foo p
toFoo m =
case m :: Maybe (p ()) of
Nothing -> NoFoo
Just _ -> YesFoo (fromJust m)
Run Code Online (Sandbox Code Playgroud)
该fromJust是恶心!toFoo实际上是总数,因为参数确保m @a行为完全相同m @(),但这是粗略的.有没有更干净的方式?
编辑:rampion指出,这可以写得更简洁,仍然有fromJust.我刚刚意识到它可以做得有点幽默,取笑新手:
toFoo m
| isNothing m = NoFoo
| otherwise = YesFoo (fromJust m)
Run Code Online (Sandbox Code Playgroud)
我认为避免创建一个thunk以应用的唯一方法fromJust是获得超级邪恶:
toFoo Nothing = NoFoo
toFoo (Just x) = YesFoo (unsafeCoerce# x)
Run Code Online (Sandbox Code Playgroud)
到目前为止我能想到的最好的方法仍然是使用fromJust,但它更简单:
toFoo :: forall p.
(forall a. Maybe (p a))
-> Foo p
toFoo Nothing = NoFoo
toFoo m = YesFoo $ fromJust m
Run Code Online (Sandbox Code Playgroud)