Function 错误-推断的类型不够通用

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

我正在尝试用Haskell编写一个简单的高阶函数,它包含两个参数:

  • 任何类型函数的列表
  • (数字或
    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