Functions to Polymorphic data types

后端 未结 3 1859
青春惊慌失措
青春惊慌失措 2021-01-13 12:37

data Foo a is defined like:

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

instance Show a =         


        
3条回答
  •  爱一瞬间的悲伤
    2021-01-13 13:20

    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
    

提交回复
热议问题