function - 错误 - 推断类型不够通用

标签 function haskell types

我正在尝试在 Haskell 中编写一个简单的高阶函数,它需要两个参数:

  1. 任何类型的函数列表。
  2. (数字或 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,2401,4096]

函数的类型必须是:

apply :: Ord u => [v->u]->[v]->[u]

为此,我使用了两个辅助函数并使用了递归。我的程序是这样的:

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 :: <b>Ord u => [v->u]->[v]->[u]</b>
apply p s = <b>myApply p s []</b>              --line 59--

myApply :: <b>Ord u => [v->u]->[u]->[u]->[u]</b>
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 函数立即调用 myApply 函数。由于 myApply 有签名 [v -> u] -> [u] -> [u] -> [u],这意味着 apply 只能有签名 [v->u] -> [u] -> [u].

快速解决方法是将 myApplymyApplyList 概括[v -> u] -> [v] -> [u] -> [u]。现在编译也会检测到您在 applyList 函数中犯的错误:您忘记在 head num_list 上调用 f。所以你可以修复它并获取以下代码:

apply :: Ord u => [v->u]->[v]->[u]             
apply p s = myApply p s []              --line 59--

myApply :: Ord u => [v->u]-><b>[v]</b>->[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)-><b>[v]</b>->[u]->[u]
applyList f num_list starterlist
    | null num_list = starterlist
    | otherwise = applyList f (tail num_list) ( (<b>f (</b>head num_list<b>)</b>) :     starterlist )

尽管如此,这段代码非常不优雅,并且使用了许多函数和参数的方式。您可以将其完全替换为单个列表推导:

apply :: [v -> u] -> [v] -> [u]
apply fs xs = [f x | f <- fs, x <- xs]

根据您的评论,您还必须在该过程的后期对值进行排序,您可以使用 sort::Ord a => [a] -> [a] 内置函数来执行此操作:

-- sorting variant
apply :: <b>Ord u =></b> [v -> u] -> [v] -> [u]
apply fs xs = <b>sort</b> [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]

关于function - 错误 - 推断类型不够通用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43184002/

相关文章:

php - 直接使用函数中的数组,无需先分配变量

R哪个函数运行另一个函数

c++ - 通过迭代器调用函数?

haskell - 如何在给定条件的情况下退出haskell中的main

c - 我的二维数组之一出现段错误 (11)?

c++ - 在模板本身中检索最里面的模板类型

c++ - 如何在 C++ 中查找函数的所有调用者?

haskell - Haskell 任务的 Makefile 示例

haskell - 如何配置 GHCi 自动导入模块

c - 在 C 中动态创建一个 TYPE 数组