Function 错误-推断的类型不够通用
我正在尝试用Haskell编写一个简单的高阶函数,它包含两个参数:Function 错误-推断的类型不够通用,function,haskell,types,Function,Haskell,Types,我正在尝试用Haskell编写一个简单的高阶函数,它包含两个参数: 任何类型函数的列表 (数字或Strings或Boolean等)的列表-->任何类型 函数应将第一个列表中的所有函数应用于第二个列表中的所有元素,将值存储在列表中,然后返回列表。该计划的一个例子是: Main> apply [(^2),(^3),(^4)] [2..8] --result: --[4,8,9,16,25,27,32,36,49,64,81,125,128,216,256,343,512,625,1296,24
String
s或Bool
ean等)的列表-->任何类型Main> apply [(^2),(^3),(^4)] [2..8]
--result: --[4,8,9,16,25,27,32,36,49,64,81,125,128,216,256,343,512,625,1296,2401,4096]
函数的类型必须为:
apply :: Ord u => [v->u]->[v]->[u]
为此,我使用了两个helper函数和递归。我的计划是:
apply :: Ord u => [v->u]->[v]->[u]
apply p s = myApply p s [] --line 59--
myApply :: Ord u => [v->u]->[u]->[u]->[u]
myApply f_list num_list starterlist
| null f_list = starterlist
| otherwise = myApply (tail f_list) (num_list) ( applyList (head f_list) num_list starterlist )
applyList :: Ord u => (v->u)->[u]->[u]->[u]
applyList f num_list starterlist
| null num_list = starterlist
| otherwise = applyList f (tail num_list) ( (head num_list) : starterlist )
我得到一个错误:
ERROR "Lab2.hs":59 - Inferred type is not general enough
*** Expression : applyList
*** Expected type : Ord a => (b -> a) -> [a] -> [b] -> [a]
*** Inferred type : Ord a => (a -> a) -> [a] -> [a] -> [a]
知道类型有什么问题吗?出现此错误的原因是存在冲突的类型签名:
apply :: Ord u => [v->u]->[v]->[u]
apply p s = myApply p s [] --line 59--
myApply :: Ord u => [v->u]->[u]->[u]->[u]
myApply f_list num_list starterlist
| null f_list = starterlist
| otherwise = myApply (tail f_list) (num_list) ( applyList (head f_list) num_list starterlist )
然而,这段代码是相当不公平的,它使用了一种方法来处理许多函数和参数。您可以将其完全替换为单个列表:
apply :: [v -> u] -> [v] -> [u]
apply fs xs = [f x | f <- fs, x <- xs]
这将生成所需的结果:
Prelude Data.List> (\fs xs -> sort [f x | f <- fs, x <- xs]) [(^2),(^3),(^4)] [2..8]
[4,8,9,16,16,25,27,36,49,64,64,81,125,216,256,343,512,625,1296,2401,4096]
Prelude Data.List>(\fs xs->sort[f x | f主题的变体:考虑到Willem的评论指出这是一个非常复杂的代码(使其难以分析),我将从一个更简单的代码开始,而不说明任何类型,首先获得一个简单的工作用例(即,一个生成预期输出的函数),仍在使用辅助函数和递归:
apply fs [] = []
apply [] xs = []
apply (f:fs) xs = (helper f xs) ++ (apply fs xs)
helper f [] = []
helper f (x:xs) = f x : helper f xs
然后我会要求Haskell编译器提供它推断出的签名类型的信息:
*Main> :t apply
apply :: [t1 -> t] -> [t1] -> [t]
通过意识到t1->t
映射到您的v->u
,我可以看到类型签名也可以写成:
[v -> u] -> [v] -> [u]
对帮助程序执行类似操作后,您将得到以下结果:
apply :: [v->u] -> [v] -> [u]
apply fs [] = []
apply [] xs = []
apply (f:fs) xs = (helper f xs) ++ (apply fs xs)
helper :: (v -> u) -> [v] -> [u]
helper f [] = []
helper f (x:xs) = f x : helper f xs
从这里开始,您可以通过添加Ord
约束,以及建立排序功能等来解决问题。为什么类型应该是Ord u
?练习说它一定是Ord ub,但在您的代码中没有任何地方使用Ord
提供的功能:您不与
进行比较,是的,我必须对值进行排序同样,但我现在不关心这个问题。这是列表的应用程序实例。您可以使用
。
[v -> u] -> [v] -> [u]
apply :: [v->u] -> [v] -> [u]
apply fs [] = []
apply [] xs = []
apply (f:fs) xs = (helper f xs) ++ (apply fs xs)
helper :: (v -> u) -> [v] -> [u]
helper f [] = []
helper f (x:xs) = f x : helper f xs