有没有办法在声音时推动foralls过去的构造函数?

时间:2017-07-07 01:36:29

标签: haskell

假设我有

data Foo p =
    NoFoo
  | YesFoo (forall a. p a)

我可以写

fromFoo :: Foo p -> Maybe (p a)
fromFoo NoFoo = Nothing
fromFoo (YesFoo p) = Just p

它也可以走另一条路:

toFoo :: forall p.
         (forall a. Maybe (p a))
      -> Foo p
toFoo m =
  case m :: Maybe (p ()) of
    Nothing -> NoFoo
    Just _ -> YesFoo (fromJust m)

fromJust很恶心! toFoo实际上是总计,因为参数确保m @a的行为与m @()完全相同,但这很严重。有没有更清洁的方式?

编辑:rampion指出这可以更简洁地编写,仍然使用fromJust。我刚刚意识到它可以做得有点幽默,取笑新手:

toFoo m
  | isNothing m = NoFoo
  | otherwise = YesFoo (fromJust m)

我认为避免创建一个thunk来应用fromJust的唯一方法就是获得超级恶魔:

toFoo Nothing = NoFoo
toFoo (Just x) = YesFoo (unsafeCoerce# x)

1 个答案:

答案 0 :(得分:1)

到目前为止,我能提出的最佳效果仍然使用fromJust,但它更简单:

toFoo :: forall p.
         (forall a. Maybe (p a))
      -> Foo p
toFoo Nothing = NoFoo
toFoo m = YesFoo $ fromJust m