GADT Functions

This is the next question Functions for polymorphic data types

The data type Questionmodels the question / answer with Message(question text) and the function ( String -> a), which maps the user input to the result of the question:

data Question where
  Simple :: (Typeable a, Show a) => Message -> (String -> a) -> Question

This CLI program should first get the name Question, find the instance using the function getQuestion, and then run Questionand print 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 does not work here: runQuestion :: (Typeable a, Show a) => Question -> IO ap No instance for (Typeable a0) arising from a use of β€˜runQuestion’.

If I remove the class ( runQuestion :: Question -> IO a) constraints , I get No instance for (Show a0) arising from a use of β€˜print.

+1
source share
2 answers

This type

Question -> IO a

", Question IO a a, ". , , ; Int, String, , Int, String - , .

, , , IO String.

type Message = String

data Question = Simple Message (String -> String)
  -- more constructors

yourName :: Question
yourName = Simple "Your name?" show

yourWeight :: Question
yourWeight = Simple "What is your weight?" (show . (read :: String -> Int))

getQuestion :: String -> Question
getQuestion "name" =  yourName
getQuestion "weight" =  yourWeight

runQuestion :: Question -> IO String
runQuestion (Simple message parser) = do
  putStrLn message
  ans <- getLine
  return $ parser ans

main = getLine >>= (runQuestion . getQuestion) >>= putStrLn

, GADT:

type Message = String

data Question where
  Simple :: Message -> (String -> Answer) β†’ Question
  -- more constructors

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

instance Show Answer where
  show (Easy a) = show a

yourName :: Question
yourName = Simple "Your name?" Easy

yourWeight :: Question
yourWeight = Simple "What is your weight?" (Easy . (read :: String -> Int))

getQuestion :: String -> Question
getQuestion "name" =  yourName
getQuestion "weight" =  yourWeight

runQuestion :: Question -> IO Answer
runQuestion (Simple message parser) = do
  putStrLn message
  ans <- getLine
  return $ parser ans

main = getLine >>= (runQuestion . getQuestion) >>= print

.

+5

, , .

, , " ".

-, :

Simple :: forall a. (Typeable a, Show a) =>
          Message -> (String -> a) -> Question

Question

Simple {a}{typeableDict4a}{showDict4a} message parser

. "", Typeable Show.

. , .

runQuestion :: forall b. (Typeable b, Show b) => Question -> IO b

, , runQuestion, , Question. .

runQuestion {b}{typeableDict4b}{showDict4b}
  (Simple {a}{typeableDict4a}{showDict4a} message parser) = do
                        -- so parser :: String -> a
      putStrLn message  -- ok, as message :: String
      ans <- getLine    -- ensures ans :: String
  return $ parser ans   -- has type IO a, not IO b

parser a, Question, b, runQuestion. , , .

, print

print :: forall c. Show c => c -> IO ()

main = getLine >>= (runQuestion . getQuestion) >>= print

main = getLine >>=
  (runQuestion {b}{typeableDict4b}{showDict4b} . getQuestion) >>=
  print {b}{showDict4b}

runQuestion {b} IO b, , print c , runQuestion b, b, Typeable, Show. Typeable ( runQuestion); Show print .

, - , runQuestion , , - ( ) ,

typeFrom :: Question -> *
typeFrom (Simple {a}{typeableDict4a}{showDict4a} message parser) = a

runQuestion :: (q :: Question) -> IO (typeFrom q)

, , Haskell: ", ". , , , . print , .

+4

Source: https://habr.com/ru/post/1652447/


All Articles