Haskell 中排列的打印长度问题

use*_*264 -1 haskell

我刚开始学习 Haskell,但我遇到了困难,因为错误消息非常神秘。特别是,当我运行这个应该打印字符串排列数的代码时,我不理解错误消息,

import Data.List

main::IO()
main = do
        str <- getLine
        print putStrLn $ length $ nub $ permutations str
Run Code Online (Sandbox Code Playgroud)

我得到的错误信息是

在此处输入图片说明

但是,当我在 REPL 中运行它时,我没有收到这样的错误:

在此处输入图片说明

Wil*_*ess 7

print putStrLn $ length $ nub $ permutations str
Run Code Online (Sandbox Code Playgroud)

被 Haskell 解析为

print putStrLn ( length ( nub ( permutations str )))
Run Code Online (Sandbox Code Playgroud)

即它调用print2 个参数,putStrLnlength (nub (permutations str))

您只想使用一个参数调用它,因此还需要一对括号:

print ( putStrLn ( length ( nub ( permutations str ))))
Run Code Online (Sandbox Code Playgroud)

这可以$通过添加一个 s来实现,如

print $ putStrLn $ length $ nub $ permutations str
Run Code Online (Sandbox Code Playgroud)

这仅解决了代码的语法问题。

当然printwithputStrLn是多余的。putStrLn已经完成了所有输出print会做的事情(甚至在此之后再输出一个换行符)。

另一方面putStrLn需要一个字符串,但length产生一个整数。要将其转换为字符串,show可以使用该函数,该函数在print内部自行调用。

所以要么

print            $ length $ nub $ permutations str
Run Code Online (Sandbox Code Playgroud)

或者

putStrLn $ show $ length $ nub $ permutations str
Run Code Online (Sandbox Code Playgroud)

从 GHCi 中可以看出:

> :t print           . length . nub . permutations
  :: Eq a => [a] -> IO ()

> :t putStrLn . show . length . nub . permutations
  :: Eq a => [a] -> IO ()
Run Code Online (Sandbox Code Playgroud)

如果有型,它使某些意义上说,至少。


Fyo*_*kin 5

putStrLn接受一个类型String为的参数,正如其签名所证明的那样。

length返回Int,正如其签名所证明的那样。

很明显,尝试将结果length作为参数传递putStrLn会导致类型不匹配。Int不匹配String。就如此容易。

print另一方面,function接受任何类型的参数(请参阅签名),只要该类型有一个Show实例,就Int可以。所以你可以替换putStrLnprint

print $ length $ nub $ permutations str
Run Code Online (Sandbox Code Playgroud)