怎么做"看不见" Haskell中的函数参数有效吗?

时间:2017-11-18 00:44:35

标签: haskell

我所谈论的一个例子是takeWhile

takeWhile :: (a -> Bool) -> [a] -> [a] 

使用示例

takeWhile (< 3) [1,2,3,4,1,2,3,4] == [1,2]

据我所知,(< 3)成为(a < 3),其中a是要检查的列表中的当前项目。

这是如何在Haskell中完成的,我怎样才能移动到a所以我可以做的事情

takeWhile ((length a) < 4) ["aaa", "aaaaa"]

3 个答案:

答案 0 :(得分:9)

(< 3)被称为&#34;部分&#34;并且仅适用于中缀运算符。编写缩写函数是一种语法糖。 (< 3)相当于\x -> x < 3(3 <)相当于\x -> 3 < x

因此,(< 3)是一个返回Bool的参数的函数。这正是takeWhile所期望的。

使用length,您必须完整编写一个函数:

takeWhile (\x -> length x < 4) ["aaa", "aaaaa"]

或定义您自己可以理解的功能:

shorterThan n x = length x < n

takeWhile (shorterThan 4) ["aaa", "aaaaa"]

如果您喜欢冒险,可以写

takeWhile ((< 4) . length) ["aaa", "aaaaa"]

或者可能以更易读的方式

(??) = flip (.)

takeWhile (length ?? (< 4)) ["aaa", "aaaaa"]

答案 1 :(得分:3)

没有任何地方,你必须记住Haskell中的每个函数都被弄清楚了,所以,在(+)函数中思考,你可以做下一个,首先考虑类型:

(+) :: Num a => a -> a -> a

现在我可以做我的自定义plusOne,plusTwo等,这要快得多,感谢curryfication,因为

(+) :: Num a => a -> a -> a

有&#34;隐含的paranthesis&#34;而且看起来很像:

(+) :: Num a => a -> (a -> a)

意思是给我一个数字给你一个功能,所以:

plusOne :: Num a => a -> a
plusOne = (+1)

plusTwo :: Num a => a -> a
plusTwo = (+2)
你能看到吗?你通过给它添加两个参数中的一个来转换新函数中的(+)<>函数也一样,你可以创建函数greaterThanTen这样:

greaterThanTen :: (Num a, Ord a) => a -> a
greaterThanTen = (>10)

因此,在您takeWhile (< 3)的示例中,您的(< 3)是函数&#34;少于3&#34;,如果您&#34;阅读&#34;所有的功能都是&#34;当n小于3&#34;

您可以通过使用:t命令

询问类型,在控制台中使用它
  :t (< 3)
(< 3) :: (Num a, Ord a) => a -> Bool

答案 2 :(得分:3)

takeWhile的第一个参数是谓词;这是你的一元函数(< 3),当参数具有数字语义且小于3时,这是正确的。当谓词第一次不为真时,此选项将应用于每个列表成员,构成新列表并终止。已通过的元素构成结果列表。

您的示例几乎是正确的,您只能将其转换为谓词形式,即创建一元函数,当参数(字符串)的长度小于4时,这是正确的。这可以通过

(\a -> (length a) < 4)

然后

takeWhile (\a -> (length a) < 4) ["aaa", "aaaaa"]

应该做你期望的事。