tripleEven :: [Int] -> [Int]
tripleEven list = case list of
[] -> []
[x:xs]
| (x `mod` 2) == 0 = triple x tripleEven xs
| otherwise = tripleEven xs
where triple = (3*)
我一直收到以下错误:
parse error on input `='
Perhaps you need a 'let' in a 'do' block?
e.g. 'let x = 5' instead of 'x = 5'
|
71 | | (x `mod` 2) == 0 = triple x tripleEven xs
我希望它通过一个列表,如果数字甚至是三倍。如果是奇数,那么移动到下一个数字直到结束。我是Haskell的新手,只学习语法。如果有人能解释这里到底出了什么问题,那将会很高兴。谢谢。
答案 0 :(得分:3)
这里有一些问题:
[x:xs]
作为非空列表模式。但是列表有两个数据构造函数:[]
和(x:xs)
(注意圆括号,实际上括号实际上不是构造函数的一部分,它只是冒号运算符(:)
); triple x tripleEven xs
,您不构造新列表:首先计算triple x
,然后Haskell旨在执行函数调用,并将该值作为函数。odd
,则在列表上执行递归,因此您不会将这些值放入结果中。我们可以将问题解决到:
tripleEven :: [Int] -> [Int]
tripleEven [] = []
tripleEven (x:xs) | even x = (3*x) : tripleEven xs
| otherwise = x : tripleEven xs
但是在这里你基本上执行映射:你可以将函数调用到列表的每个元素,所以我们可以构造一个特殊的映射函数:
tripleEven :: [Int] -> [Int]
tripleEven = map f
where f x | even x = 3 * x
| otherwise = x
答案 1 :(得分:3)
这是一个编写函数的递归方法,我只修复了我在代码中注意到的错误。
tripleEven :: [Int] -> [Int]
tripleEven [] -> []
tripleEven (x: xs) = case mod x 2 of
0 -> (3*x) : tripleEven xs
_ -> tripleEven xs
tripleEven [1,2,3,4]
# outputs
[6, 12]
TripleEven
也可以被视为map
& filter
操作或列表理解
tripleEven xs = map (*3) $ filter even xs
tripleEven xs = [x*3 | x <- xs, even x]
最后,如果要在where子句中定义triple
:
tripleEven :: [Int] -> [Int]
tripleEven [] = []
tripleEven (x: xs) = case mod x 2 of
0 -> trip x : tripleEven xs
where trip = (*3)
_ -> tripleEven xs
答案 2 :(得分:0)
列表类型是一个仿函数,也是一个monad。所以我相信做这项工作的正确方法就是在列表上使用fmap :: Functor f => (a -> b) -> f a -> f b
。但是,仅对于列表类型,我们已经拥有与map :: (a -> b) -> [a] -> [b]
完全相同的fmap
函数。
因此;
Prelude> let trev = map (\n -> if even n then n*3 else n)
Prelude> trev [1,2,3,4]
[1,6,3,12]
应该完美地完成这项工作并且它已被提及。
我们也可以从monadic的角度处理这个任务。然后我们需要一个monadic函数来运行我们的列表元素。是什么让我们的lambda函数monadic在这里是return
指令。
Prelude> let trev ns = ns >>= \n -> if even n then return (n*3) else return n
Prelude> trev [1,2,3,4]
[1,6,3,12]