Haskell 带模的过滤运算
Haskell filter operation with modulo
我正在尝试使用 Haskell 中的 "filter",但我卡住了。
我想像这样在一个函数中同时使用过滤器和模数
multipleOf7 :: [Int] -> [Int]
multipleOf7 x = filter (test) x
where test = x mod 7 == 0
我也试过使用 mod
但它不起作用。
你要明白的是 Haskell 有一个 "very" 统一的语法(没有那么多 "special" 的情况)。您使用参数 x y
和 f x y
调用函数 f
。现在 mod
就像所有其他函数一样只是一个普通函数。所以你应该调用它:
mod x 7
您还可以使用反向函数调用二元运算符,其中的函数如下:
x `mod` 7
因此您可以通过以下方法解决问题:
multipleOf7 :: [Int] -> [Int]
multipleOf7 x = filter (test) x
where test x = mod x 7 == 0
或更清洁:
multipleOf7 :: [Int] -> [Int]
multipleOf7 = filter test
where test <b>x</b> = <b>mod x 7</b> == 0
您还可以重写 test
函数,这样:
test = (0 ==) . flip mod 7
或制作更短的过滤器,如:
multipleOf7 :: Integral b => [b] -> [b]
multipleOf7 = filter ((0 ==) . flip mod 7)
(opinion) 个人认为mod x 7
初看确实怪怪的。但过了一段时间后,您开始发现这很有用,因为它节省了很多大脑循环,而不考虑复杂的 syntax/grammar 规则。
你应该用反引号写 mod
x `mod` 7 == 0
或者正常使用
mod x 7 == 0
在haskell中你可以使用任何函数作为中缀。
如果你定义一个像
这样的简单函数
myFunction x y = x * y
然后,如果你愿意,你可以像这样使用它:
z = 40 `myFunction` 50
如果你愿意,你也可以用中缀风格定义函数。
x `myFunction` y = x * y
那将完全相同,您仍然可以用另一种方式称呼它:
z = myFunction 40 50
此外,本着同样的精神,您可以轻松地在Haskell中定义自定义中缀operators/symbols。例如:
(-!!->) a b = (a,b)
-- or identically, but no need for backticks for infix operators
a -!!-> b = (a,b)
可以这样使用:
c = 1 -!!-> 2
-- and now c == (1,2)
但这应该谨慎使用,仔细选择您的自定义交易品种,并明确意图提高可读性恕我直言。
因为 filter :: (a -> Bool) -> [a] -> [a]
而在你的情况下 a = Int,
multipleOf7 :: [Int] -> [Int]
multipleOf7 ns = filter f ns
where
f :: Int -> Bool
f i = i `mod` 7 == 0
像 Willem Van Onsem,我可能会 loosen the Int into an Integral a => a, since the library function mod :: Integral a => a -> a -> a
is just as general. I would also parameterize the 7 into an n, ditch the ns 并将 f 写成 lambda:
multipleOf :: Integral a => a -> [a] -> [a]
multipleOf n = filter (\i -> i `mod` n == 0)
Willem Van Onsem 然后将其重写为 pointfree style:
multipleOf7 :: Integral a => [a] -> [a]
multipleOf7 = filter ((0 ==) . flip mod 7)
Pointfree 样式有时更具可读性。我认为这里不是这种情况。此处提供另一种变体,
multipleOf :: Integral a => a -> [a] -> [a]
multipleOf n = filter ((== 0) . (`mod` n))
不过,我更喜欢带有 where
或 lambda 的第一个版本。
我正在尝试使用 Haskell 中的 "filter",但我卡住了。 我想像这样在一个函数中同时使用过滤器和模数
multipleOf7 :: [Int] -> [Int]
multipleOf7 x = filter (test) x
where test = x mod 7 == 0
我也试过使用 mod
但它不起作用。
你要明白的是 Haskell 有一个 "very" 统一的语法(没有那么多 "special" 的情况)。您使用参数 x y
和 f x y
调用函数 f
。现在 mod
就像所有其他函数一样只是一个普通函数。所以你应该调用它:
mod x 7
您还可以使用反向函数调用二元运算符,其中的函数如下:
x `mod` 7
因此您可以通过以下方法解决问题:
multipleOf7 :: [Int] -> [Int]
multipleOf7 x = filter (test) x
where test x = mod x 7 == 0
或更清洁:
multipleOf7 :: [Int] -> [Int]
multipleOf7 = filter test
where test <b>x</b> = <b>mod x 7</b> == 0
您还可以重写 test
函数,这样:
test = (0 ==) . flip mod 7
或制作更短的过滤器,如:
multipleOf7 :: Integral b => [b] -> [b]
multipleOf7 = filter ((0 ==) . flip mod 7)
(opinion) 个人认为mod x 7
初看确实怪怪的。但过了一段时间后,您开始发现这很有用,因为它节省了很多大脑循环,而不考虑复杂的 syntax/grammar 规则。
你应该用反引号写 mod
x `mod` 7 == 0
或者正常使用
mod x 7 == 0
在haskell中你可以使用任何函数作为中缀。 如果你定义一个像
这样的简单函数myFunction x y = x * y
然后,如果你愿意,你可以像这样使用它:
z = 40 `myFunction` 50
如果你愿意,你也可以用中缀风格定义函数。
x `myFunction` y = x * y
那将完全相同,您仍然可以用另一种方式称呼它:
z = myFunction 40 50
此外,本着同样的精神,您可以轻松地在Haskell中定义自定义中缀operators/symbols。例如:
(-!!->) a b = (a,b)
-- or identically, but no need for backticks for infix operators
a -!!-> b = (a,b)
可以这样使用:
c = 1 -!!-> 2
-- and now c == (1,2)
但这应该谨慎使用,仔细选择您的自定义交易品种,并明确意图提高可读性恕我直言。
因为 filter :: (a -> Bool) -> [a] -> [a]
而在你的情况下 a = Int,
multipleOf7 :: [Int] -> [Int]
multipleOf7 ns = filter f ns
where
f :: Int -> Bool
f i = i `mod` 7 == 0
像 Willem Van Onsem,我可能会 loosen the Int into an Integral a => a, since the library function mod :: Integral a => a -> a -> a
is just as general. I would also parameterize the 7 into an n, ditch the ns 并将 f 写成 lambda:
multipleOf :: Integral a => a -> [a] -> [a]
multipleOf n = filter (\i -> i `mod` n == 0)
Willem Van Onsem 然后将其重写为 pointfree style:
multipleOf7 :: Integral a => [a] -> [a]
multipleOf7 = filter ((0 ==) . flip mod 7)
Pointfree 样式有时更具可读性。我认为这里不是这种情况。此处提供另一种变体,
multipleOf :: Integral a => a -> [a] -> [a]
multipleOf n = filter ((== 0) . (`mod` n))
不过,我更喜欢带有 where
或 lambda 的第一个版本。