I have a problem compiling the following code on GHC 6.12.3 and I don't understand why.
The purpose of function test2
is to return a function that uses an integer to get a string element from a list (the list is created from the first nodes from a pair-list).
The IO bits is needed as test2
is used by another function using IO.
type PairList = [(String, String)]
test1 :: [String] -> Int -> String
test1 list x = list !! x
test2 :: PairList -> IO (Int -> String)
test2 pl = do
f <- [fst x | x <- pl] :: IO [String]
return test1 f
GHC gives me this error:
Test.hs:8:6:
Couln't match expected type 'IO [String]'
against inferred type '[a]'
In a stmt of a 'do' expression:
f <- [fst x | x <- pl] :: IO [String]
In the expression:
do { f <- [fst x | x <- pl] :: IO [String];
return test1 f }
...
Edit:
If you want to do this directly (you need extra IO while computing test2
), you can do something like
test2 :: PairList -> IO (Int -> String)
test2 pl = do
putStrLn "Hi Mum!"
return (test1 [fst x | x <- pl])
Your original code didn't work because when you did f <- [...]
, you were using the list monad as if it were the IO monad.
Purely as an example, you can use that like this:
myactions = do
putStrLn "Please enter a list of (String,String) pairs:"
pl <- readLn -- which you'd have to write, or derive Read and use readLn
f <- test2 pl
putStrLn "please enter a number:"
n <- readLn
putStrLn $ f n
Which would give you behaviour like
*Main> myactions
Please enter a list of (String,String) pairs:
[("hi","yes"),("oops","bye")]
Hi Mum!
please enter a number:
1
oops
Original answer:
I don't think you need the IO
bits:
type PairList = [(String, String)]
test1 :: [String] -> Int -> String
test1 list x = list !! x
test2pure :: PairList -> (Int -> String)
test2pure pl = test1 [fst x | x <- pl]
This compiles fine, and gives results like
test2pure [("a String","ignored"), ("Another String","bye!")] 0
"a String"
If you want to use it in IO, you could use it like this:
myactions = do
pl <- readLn
let chosen = test2pure pl 3
putStrLn ("3: " ++ chosen)
Or you could write
test2IO :: PairList -> Int -> IO String
test2IO pl n = return (test2pure pl n)
If you really want to use IO ()
as a return type you can fix the compile error like this:
test2 pl = return $ test1 [fst x | x <- pl]
As AndrewC said in his answer, you probably don't need monads in this 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.