do ブロックを使用して記述した関数を書き直して、リストに同様のラムダ式を fmap できない理由を理解しようとしています。
私は次のものを持っています:
-- This works
test1 x = do
let m = T.pack $ show x
T.putStrLn m
test1 1
プロデュース
1
しかし
-- This fails
fmap (\x -> do
let m = T.pack $ show x
T.putStrLn m
) [1..10]
-- And this also fails
fmap (\x -> do
T.putStrLn $ T.pack $ show x
) [1..10]
エラーあり:
<interactive>:1:1: error:
• No instance for (Show (IO ())) arising from a use of ‘print’
• In a stmt of an interactive GHCi command: print it
私の putStrLn は、機能するものと機能しないものの間で一貫しています。インポートは同じです。印刷に必要な私の show-pack-putstrln ダンスも、機能するものと機能しないものの間で一貫しています。
ワーキングとノンワーキングの間で印刷物の使用が変化しているとはどういうことでしょうか。
更新 1
-- I was also surprised that this fails
fmap (T.putStrLn $ T.pack $ show) [1..10]
-- it seemed as similar as possible to the test1 function but mapped.
<interactive>:1:7: error:
• Couldn't match expected type ‘Integer -> b’ with actual type ‘IO ()’
• In the first argument of ‘fmap’, namely ‘(T.putStrLn $ pack $ show)’
In the expression: fmap (T.putStrLn $ pack $ show) [1 .. 10]
In an equation for ‘it’: it = fmap (T.putStrLn $ pack $ show) [1 .. 10]
• Relevant bindings include it :: [b] (bound at <interactive>:1:1)
<interactive>:1:29: error:
• Couldn't match type ‘() -> String’ with ‘String’
Expected type: String
Actual type: () -> String
• Probable cause: ‘show’ is applied to too few arguments
In the second argument of ‘($)’, namely ‘show’
In the second argument of ‘($)’, namely ‘pack $ show’
In the first argument of ‘fmap’, namely ‘(T.putStrLn $ pack $ show)’
更新 2
-- This lambda returns x of the same type as \x
-- even while incidentally printing along the way
fmap (\x -> do
let m = T.pack $ show x
T.putStrLn $ m
return x
) [1..10]
しかし、次の場合にも失敗します。
<interactive>:1:1: error:
• No instance for (Show (IO Integer)) arising from a use of ‘print’
• In a stmt of an interactive GHCi command: print it