It's a followup question of Functions to Polymorphic data types
Data type Question
models a question/answer with a Message
(the text of the question) and a function (String -> a
) that maps user's input to the result of the question:
data Question where
Simple :: (Typeable a, Show a) => Message -> (String -> a) -> Question
This CLI program should first gets the name of the Question
, find an instance using getQuestion
function and then run the Question
and print out the result.
{-# LANGUAGE GADTs #-}
import Data.Typeable
type Message = String
data Question where
Simple :: (Typeable a, Show a) => Message -> (String -> a) -> Question
-- more constructors
yourName :: Question
yourName = Simple "Your name?" id
yourWeight :: Question
yourWeight = Simple "What is your weight?" (read :: String -> Int)
getQuestion :: String -> Question
getQuestion "name" = yourName
getQuestion "weight" = yourWeight
runQuestion :: (Typeable a, Show a) => Question -> IO a
runQuestion (Simple message parser) = do
putStrLn message
ans <- getLine
return $ parser ans
main = getLine >>= (runQuestion . getQuestion) >>= print
Type checking fails at here: runQuestion :: (Typeable a, Show a) => Question -> IO a
with No instance for (Typeable a0) arising from a use of ‘runQuestion’
.
If I remove the class constraints (runQuestion :: Question -> IO a
) then I get No instance for (Show a0) arising from a use of ‘print
.