如何在 haskell 的列表中存储高阶函数数据?

How to store higher order function data in list in haskell?

我正在尝试将函数的结果数据存储在列表中,但不知道如何在代码中定义。

我认为问题出在第 10 行。

| tst x == True  = [x,xs..]

如何定义存储 tst x 结果数据的列表?

因此,预期输出如下。

Main> two_sear evn [2,4,5,8]
[2,4,8]
Main> two_sear big [101]
[101]

我目前的做法:

evn :: Int -> Bool
evn x = mod x 2 == 0

big :: Int -> Bool
big x = x > 100

two_sear::(Int -> Bool) -> [Int] -> [Int]
two_sear tst [] = []
two_sear tst (x:xs)
    | tst x == True  = [x,xs..]
    | otherwise = two_sear tst xs

您似乎想在这里使用 filter :: (a -> Bool) -> a -> a。因此,除了使用您自己的 two_sear,您还可以使用过滤器。

例如:

Prelude> filter evn [2,4,5,8]
[2,4,8]
Prelude> filter big [101]
[101]

你可以通过递归自己实现filter

filter' :: (a -> Bool) -> [a] -> [a]
filter' p = go
    where go [] = []
          go (x:xs) | p x = x : go xs
                    | otherwise = go xs

因此我们构建了一个 (x : go xs) 或更简洁 x : go xs 的列表。这是一个 "cons" 和 x 列表的头部,我们用 go xs 对列表的其余项目进行递归。

go 函数可以作为 foldr 实现:

import Data.Bool(bool)

filter' :: (a -> Bool) -> [a] -> [a]
filter' p = foldr ((bool id . (:)) <*> p) []

Prelude 已经有 even :: Integral i => i -> Bool 的实现,您可以将 big 定义为:

big :: (Num n, Ord n) => n -> Bool
big = (<) 100

或:

big :: (Num n, Ord n) => n -> Bool
big = (100 <)

除了这里已经很好的答案。 Haskell 中的函数与任何其他值一样,您当前的函数也可以柯里化(实际上 Haskell 中的每个函数都是柯里化的)。说到这里,举个例子:

fs = [(+), (*), (-), (div)]
ints = [(2,4), (5,3), (6,2), (9,3)]

applyFs :: [a -> b -> c] -> [(a, b)] -> [c]
applyFs fs ns = zipWith (($) . uncurry) fs ns

=> [6,15,4,3]

如你所见,fs是一个list a function,完全有效