我开始学习Haskell,并且遇到了困难,因为错误消息非常隐晦。特别是,当我运行此应打印字符串排列数目的代码时,我不理解错误消息,
import Data.List
main::IO()
main = do
str <- getLine
print putStrLn $ length $ nub $ permutations str
我收到的错误消息是
但是,当我在REPL中运行它时,我没有得到这样的错误:
答案 0 :(得分:7)
print putStrLn $ length $ nub $ permutations str
Haskell将解析为
print putStrLn ( length ( nub ( permutations str )))
即它使用两个参数print
和putStrLn
调用length (nub (permutations str))
。
您只想使用一个参数来调用它,因此还需要一对parens:
print ( putStrLn ( length ( nub ( permutations str ))))
这可以用$
来实现,只需再添加一个即可,
print $ putStrLn $ length $ nub $ permutations str
这仅解决了代码中的语法问题。
当然,print
与putStrLn
是多余的。 putStrLn
已经完成了print
的所有输出(甚至在此之后再输出一个换行符)。
另一方面,putStrLn
需要一个字符串,但是length
产生一个整数。要将其转换为字符串,可以使用函数show
,print
会在内部自行调用。
就是这样
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
会导致类型不匹配。 putStrLn
与Int
不匹配。就这么简单。
另一方面,函数String
可以接受任何类型的参数(请参见signature),只要该类型具有一个print
实例即可,Show
做。因此,您只需将Int
替换为putStrLn
:
print