Это Followup вопрос Functions to Polymorphic data typesФункции GADTs
типа данных Question
моделирует вопрос/ответ с Message
(текст вопроса) и функция (String -> a
), который отображает ввод пользователя в результате этого вопроса :
data Question where
Simple :: (Typeable a, Show a) => Message -> (String -> a) -> Question
Это CLI программа должна первым получает имя Question
, найти экземпляр, используя getQuestion
функцию, а затем запустить Question
и распечатать результат.
{-# 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
проверка Тип проваливает здесь: runQuestion :: (Typeable a, Show a) => Question -> IO a
с No instance for (Typeable a0) arising from a use of ‘runQuestion’
.
Если я удаляю ограничения класса (runQuestion :: Question -> IO a
), то получаю No instance for (Show a0) arising from a use of ‘print
.
Можем ли мы сделать вопрос экземпляром Monad или Category? Мне нравится, что он должен быть сложен: «Вопрос o -> (o -> Question o ') -> Вопрос o'' Таким образом, во время разработки я могу гарантировать, что вопросы будут упорядочены и будут заданы в« рациональном »порядке , – homam
Сохраняя возможность 'getQuestion :: String -> Question', возможно, первый вопрос. – homam
Оригинальный 'Question' имеет вид' * '(без параметров типа). Если вы хотите, чтобы он был параметризован по типу ответа, это совершенно другой чайник из рыбы. У вас может быть 'String-> Question', а' String-> Question a' имеет ту же проблему, с которой вы сталкиваетесь с вопросом -> IO a'. –