Functions to Polymorphic data types

拟墨画扇 提交于 2019-12-01 06:30:22

Perhaps you want to omit the type parameter from Foo.

data Foo where
  Foo :: (Typeable a, Show a) => a -> Foo

instance Show Foo where
  show (Foo a) = show a

fiveFoo :: Foo
fiveFoo = Foo (5 :: Int) -- (Foo 5) doesn't work because of ambiguity

falseFoo :: Foo
falseFoo = Foo False

getFoo :: String -> Foo
getFoo "five" = fiveFoo
getFoo "false" = falseFoo

print $ getFoo "five" -- prints '5'
print $ getFoo "false" -- prints 'False'

You can use existential types to make a data type hide and "carry" a type class like Show around.

Note that using existential types like this is considered to be an anti-pattern in Haskell, and you probably want to consider carefully whether you really want to do this: being more explicit about your types is usually simpler, better, and less prone to bugs.

However, that being said, if you really want to do this, here is how you would use existential types with your example:

{-# LANGUAGE ExistentialQuantification #-}

-- This Foo can only be constructed with instances of Show as its argument.
data Foo = forall a. Show a => Foo a

-- Note that there is no "Show a => ..." context here:
-- Foo itself already carries that constraint around with it.
instance Show Foo where
  show (Foo a) = show a


getFoo :: String -> Foo
getFoo "five" = Foo 5
getFoo "false" = Foo False

main = print . getFoo =<< getLine

Demonstration:

ghci> main
five
5
ghci> main
false
False
getFoo :: (Show a, Typeable a) => String -> Foo a
getFoo "five" = fiveFoo
getFoo "false" = falseFoo

If fiveFoo :: Foo Int and falseFoo :: Foo Bool, you're essentially asking for getFoo to return a different type depending on what value you feed it at run-time. You can't do that. In Haskell, all types must be known at compile-time.

If all you want to be able to do is convert the thing to a string, why not just store it as a string in the first place? I'm guessing the answer is that this is actually a simplification of the real problem you're trying to solve...(?)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!