0

GHC 6.12.3 で次のコードをコンパイルする際に問題があり、その理由がわかりません。

function の目的test2は、整数を使用してリストから文字列要素を取得する関数を返すことです (リストはペアリストの最初のノードから作成されます)。

IO ビットは、IOtest2を使用する別の関数で使用されるため必要です。

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は私にこのエラーを与えます:

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 }
            ...
4

2 に答える 2

1

編集:
これを直接実行したい場合(計算中に追加のIOが必要ですtest2)、次のようなことができます

test2 :: PairList -> IO (Int -> String)
test2 pl = do
     putStrLn "Hi Mum!"
     return (test1 [fst x | x <- pl])

元のコードは機能しませんでしたf <- [...]。これは、リスト モナドを IO モナドのように使用していたためです。

純粋に例として、次のように使用できます。

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

あなたに次のような振る舞いを与えるでしょう

*Main> myactions
Please enter a list of (String,String) pairs:
[("hi","yes"),("oops","bye")]
Hi Mum!
please enter a number:
1
oops

元の答え:

IOビットは必要ないと思います:

type PairList = [(String, String)]

test1 :: [String] -> Int -> String
test1 list x = list !! x

test2pure :: PairList -> (Int -> String)
test2pure pl = test1 [fst x | x <- pl] 

これは問題なくコンパイルされ、次のような結果が得られます

test2pure [("a String","ignored"), ("Another String","bye!")] 0
"a String"

IO で使用する場合は、次のように使用できます。

myactions = do
   pl <- readLn
   let chosen = test2pure pl 3
   putStrLn ("3: " ++ chosen)

または、あなたが書くことができます

test2IO :: PairList -> Int -> IO String
test2IO pl n = return (test2pure pl n)
于 2012-11-14T23:12:10.190 に答える
0

本当にリターンタイプとして使用したい場合はIO ()、次のようにコンパイルエラーを修正できます。

test2 pl = return $ test1 [fst x | x <- pl]

AndrewCが彼の答えで言ったように、おそらくこの関数にモナドは必要ありません。

于 2012-11-14T23:26:52.890 に答える