我所谈论的一个例子是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"]
答案 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"]
应该做你期望的事。