Haskell源文件中的一行与GHCI中的一行之间的差异



Haskell新手在这里,所以如果问题太简单,请原谅。只是我似乎无法掌握为什么有些东西在文件中是可以的,但在 GHCI 中却不能。例如,我在文件中有以下行:

showLst :: [[Int]] -> IO ()
showLst = putStrLn . unlines . map show

这将采用 m x n 数组并在屏幕上打印结果。一个非常方便的功能。但是,当我对GHCI进行快速检查并且我想要相同的功能时,我尝试在GHCI中定义相同的功能,如下所示:

>> let showLst = putStrLn . unlines . map show
>> showLst [[1,2,3], [4,5,6], [7,8,9]]

我收到一个类型错误。所以我尝试了几种变体:

>> (showLst [[1,2,3], [4,5,6], [7,8,9]]) :: IO ()
>> (showLst:: [[Int]] -> IO ()) [[1,2,3], [4,5,6], [7,8,9]] 
>> (showLst [[1,2,3], [4,5,6], [7,8,9]]) :: [[Int]] -> IO () -- which us wrong anyway
>> showLst [[1,2,3], [4,5,6], [7,8,9]] :: [[Int]] -> IO () -- which is also wrong

等等,他们都失败了。这似乎是一件非常简单的事情,但不知道为什么我发现这如此困难。我一定错过了一些真正基本的东西。有人可以让我知道我在做什么吗?

问题是由于单态限制,GHCi 将列表元素的默认类型设置为 ()

Prelude> let showLst = putStrLn . unlines . map show
Prelude> :t showLst 
showLst :: [()] -> IO ()

您可以禁用此限制并获取常规类型:

Prelude> :set -XNoMonomorphismRestriction 
Prelude> let showLst = putStrLn . unlines . map show
Prelude> :t showLst 
showLst :: Show a => [a] -> IO ()

或者,您可以手动指定所需的类型:

Prelude> let showLst = putStrLn . unlines . map show :: [[Int]] -> IO ()

最新更新