简体   繁体   中英

Mapping show to a list of a custom data type

As part of a large project at university to write an interpreter in Haskell for a simple custom language, I am trying to print some things to help me in my quest to write this thing.

There's a custom data type

data Prog = Prog [Func]
    deriving (Show, Read)

and when I try to print an instance of this prog in the last line of this function

interpret :: Prog -> Vars -> String -> MaybeDebug -> IO ()
interpret prog vars entry _ = do
    putStrLn "The interpreter isn't written yet.  Better get onto that!"
    putStrLn "\n\n"
    putStrLn (show prog)
    putStrLn "\n\n"
    putStrLn (show vars)
    putStrLn "\n\n"
    putStrLn (show entry)
    putStrLn "\n\n"
    putStrLn (map show [func | func <- prog, (func_name func) == entry])

I receive an error "Couldn't match expected type 'Char' with actual type 'String'.

I have been trying for some time to work out what the problem is here. Why is it mentioning chars when this list comprehension returns a list of funcs?

map show [func | func <- prog, (func_name func) == entry]

produces a list of String s, but putStrLn takes a single String , or [Char] , as argument.

So the expected type of the list elements is Char , but the actual type is String .

Depending on what output you desire, the last line should be something like

putStrLn (unlines $ map show [func | func <- prog, (func_name func) == entry])

or

mapM_ putStrLn (map show [func | func <- prog, (func_name func) == entry])

(that would be better

mapM_ print [func | func <- prog, (func_name func) == entry]

however).

Then, in the list comprehension, when you write func <- prog , prog must be a list, but the argument to interpret is a Prog , a list wrapped in a constructor Prog . You need to unwrap the list to use it in the list comprehension, for example

interpret prog@(Prog functions) vars entry _ = do

with an as-pattern, and then

func <- functions

in the list comprehension.

As stated by Daniel, the problem is that putStrLn expects a String, not a list of Strings.

I suggest intercalate to print a comma separated list.

putStrLn (intercalate ", " (map show [func | func <- prog, (func_name func) == entry]))

You need to import Data.List to get the intercalate function.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM