首页 > 解决方案 > 如何用高阶函数表达列表理解?

问题描述

这个程序的目的是使用一个高阶函数来表示一个列表推导,它需要一个函数(a -> b)和过滤器 p:(a -> Bool)和一个 list:[Int]来生成一个列表。但是,会出现一系列错误:

  1. 无法将预期类型Bool -> [Int]与实际类型匹配[b0]
  2. 该函数map应用于三个参数,但它的类型(a1 -> b0) -> [a1] -> [b0]只有两个。listcomprehension f p xs = map f filter(p xs)
  3. 无法将预期类型a1 -> b0与实际类型匹配(a, b)
  4. 无法将预期类型[a1]与实际类型匹配(a0 -> Bool) -> [a0] -> [a0]

listcomprehension :: (a -> b) -> (a -> Bool) -> [Int] -> [Int] listcomprehension f p xs = map f filter(p xs)

我尝试了一种不同的方法,我在其中写道:

listcomprehension :: (a -> b) -> [Int] -> [Int]
listcomprehension f xs = map f filter(p xs)

第二种解决方案的错误是 p 不在范围内。这导致了是否添加 p 作为导致错误的任何一种方式的两难选择,问题是如何将 p 作为参数包含在函数中?

标签: haskell

解决方案


它需要一个功能(a,b)

(a, b)不是函数(a, b)是一个 2 元组,对于一个函数,您需要将其重写为a -> b.

由于您仅使用Ints 列表,因此您不能将a -> b其用作映射函数,也不能a -> Bool用作过滤函数。这些功能应该f :: Int -> Intp :: Int -> Bool

您还以错误的方式使用括号。为了让这项工作,它应该是:

listcomprehension :: (Int -> Int) -> (Int -> Bool) -> [Int] -> [Int]
listcomprehension f xs = map f (filter p xs)

或者我们可以将此函数进一步推广到:

listcomprehension :: (a -> b) -> (a -> Bool) -> [a] -> [b]
listcomprehension f xs = map f (filter p xs)

然而,上面不是列表理解表达式。您可以使用以下方法实现这样的列表理解表达式:

listcomprehension :: (a -> b) -> (a -> Bool) -> [a] -> [b]
listcomprehension f xs = [f x | x <- xs, p x]

推荐阅读