我下面有三个例子。我试图理解为什么在第一种情况下,我可以分配变量,但不能打印它。在第二个中,如果我将整个内容分配为字符串,则以后可以打印它。但是在第三种情况下,如果我先进行计算然后尝试打印,则会失败:
{-# LANGUAGE DeriveGeneric, OverloadedStrings, RankNTypes, KindSignatures, FlexibleContexts, AllowAmbiguousTypes #-}
:ext OverloadedStrings
import Data.Text as T
import Data.Text.IO as T
-- This works
mm1 x = do
T.putStrLn "Testing m1"
let m = T.pack $ show x
y = x * 2
T.putStrLn "Here is m"
T.putStrLn m
T.putStrLn "y has been assigned successfully, but not printed."
mm1 10
-- This also works
mm2 x = do
T.putStrLn "Testing m2"
let m = T.pack $ show x
y = T.pack $ show $ x * 2
T.putStrLn "Here is m"
T.putStrLn m
T.putStrLn "Here is y"
T.putStrLn y -- this prints fine
mm2 10
-- But This does not work
mm3 x = do
T.putStrLn "Testing m3"
let m = T.pack $ show x
y = x * 2
T.putStrLn "Here is m"
T.putStrLn m
T.putStrLn "y has been assigned cannot be printed:"
T.putStrLn T.pack $ show y
mm3 10
我的错误是:
<interactive>:8:9: error:
• Couldn't match expected type ‘String -> IO b’ with actual type ‘IO ()’
• The first argument of ($) takes one argument,
but its type ‘IO ()’ has none
In a stmt of a 'do' block: T.putStrLn pack $ show y
In the expression:
do T.putStrLn "Testing m3"
let m = pack $ show x
y = x * 2
T.putStrLn "Here is m"
T.putStrLn m
....
• Relevant bindings include mm3 :: a -> IO b (bound at <interactive>:1:1)
<interactive>:8:20: error:
• Couldn't match expected type ‘Text’ with actual type ‘String -> Text’
• Probable cause: ‘pack’ is applied to too few arguments
In the first argument of ‘T.putStrLn’, namely ‘pack’
In the expression: T.putStrLn pack
In a stmt of a 'do' block: T.putStrLn pack $ show y
我不明白这个错误告诉我什么。
具体来说,如果
let
y = T.pack $ show $ x * 2
T.putStrLn y -- this prints fine
有效。为什么:
let
y = x * 2
T.putStrLn T.pack $ show y
失败?这些应该完全相同,对吧?
答案 0 :(得分:8)
不,它们并不相同。
第一个内联解析为:
T.putStrLn (T.pack (show (x * 2)))
第二个解析为:
(T.putStrLn T.pack) (show (x * 2))
您不能将pack
函数的StrLn放入函数show y
并将其结果作为函数应用到输入T.putStrLn $ T.pack $ show (x * 2)
。您可能想要:
T.putStrLn (T.pack (show (x * 2)))
或
T.putStrLn T.pack $ show y
^
|
Couldn't match expected type ‘Text’ with actual type ‘String -> Text’
编辑:阅读错误消息,这是它试图帮助您了解的内容:
T.pack
值String -> Text
的类型为T.putStrLn
,但是类型检查器基于Text
知道,如果工作正常,则该值应该为 T.putStrLn T.pack $ show y
|
Couldn't match expected type ‘String -> IO b’ with actual type ‘IO ()’
• The first argument of ($) takes one argument,
but its type ‘IO ()’ has none
。
$
如果T.putStrLn T.pack
的第一个参数T.putStrLn
键入check,则结果由IO ()
的结果$
决定。但是,a -> b
的第一个参数必须“采用一个参数”(输入IO ()
),而{
"message": "Unauthenticated."
}
显然不需要。