Haskell中排列的打印长度问题

时间:2019-12-18 16:15:03

标签: haskell

我开始学习Haskell,并且遇到了困难,因为错误消息非常隐晦。特别是,当我运行此应打印字符串排列数目的代码时,我不理解错误消息,

import Data.List

main::IO()
main = do
        str <- getLine
        print putStrLn $ length $ nub $ permutations str

我收到的错误消息是

enter image description here

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

enter image description here

2 个答案:

答案 0 :(得分:7)

print putStrLn $ length $ nub $ permutations str
Haskell将

解析为

print putStrLn ( length ( nub ( permutations str )))

即它使用两个参数printputStrLn调用length (nub (permutations str))

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

print ( putStrLn ( length ( nub ( permutations str ))))

这可以用$来实现,只需再添加一个即可,

print $ putStrLn $ length $ nub $ permutations str

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

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

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

就是这样

print            $ length $ nub $ permutations str

putStrLn $ show $ length $ nub $ permutations str

在GHCi中可以看到:

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

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

如果具有类型,则至少有意义。

答案 1 :(得分:5)

#include <iostream> using namespace std; int partition(int *arr, int start, int end) { int pivot = start; int temp; int temp2; while (start < end) { while (arr[start] <= arr[pivot]) start++; while (arr[end] > arr[pivot]) end--; if (start < end) { temp = arr[start]; arr[start] = arr[end]; arr[end] = temp; } } temp2 = arr[pivot]; arr[pivot] = arr[end]; arr[end] = temp2; return end; } void quickSort(int input[], int size) { int lb = 0; int ub = size - 1; int loc; if (lb < ub) { loc = partition(input, lb, ub); quickSort(input, loc - 1); quickSort(input + loc + 1, ub - loc); } else return; } int main() { int n; cin >> n; int *input = new int[n]; for (int i = 0; i < n; i++) { cin >> input[i]; } quickSort(input, n); for (int i = 0; i < n; i++) { cout << input[i] << " "; } delete[] input; } 采用类型putStrLn的参数,如its signature所示。

String返回length,如its signature所示。

因此,显然,尝试将Int的结果作为参数传递给length会导致类型不匹配。 putStrLnInt不匹配。就这么简单。

另一方面,函数String可以接受任何类型的参数(请参见signature),只要该类型具有一个print实例即可,Show做。因此,您只需将Int替换为putStrLn

print