Haskell 使用';让';在';如果';表达
我需要一个这样工作的函数:Haskell 使用';让';在';如果';表达,haskell,Haskell,我需要一个这样工作的函数: foo :: Integer -> Integer -> [Integer] foo a b = do let result = [] let Coord x y = boo a b if x > 0 let result = result ++ [3] if y > 0 let result = r
foo :: Integer -> Integer -> [Integer]
foo a b = do
let result = []
let Coord x y = boo a b
if x > 0
let result = result ++ [3]
if y > 0
let result = result ++ [5]
if x < a
let result = result ++ [7]
if y < b
let result = result ++ [9]
result
let result1 = if x > 0 then [3] else []
let result2 = if y > 0 then result1 ++ [5] else result1
let result3 = if x < a then result2 ++ [7] else result2
if y < b then result3 ++ [9] else result3
如何检查多个表达式并在列表中添加新元素?
我不仅搜索命令式解决方案,还搜索功能性解决方案。编辑:感谢sepp2k指出了我的意图。这比我戴着哈斯凯尔彩色眼镜摸索更迫切 下面是一个快速解决方案:
result = (if x > 0 then [3] else []) ++
(if y > 0 then [5] else []) ++
(if x < a then [7] else []) ++
(if y < b then [9] else [])
result=(如果x>0,则[3]否则[])++
(如果y>0,则[5]否则[])++
(如果x
(旧答案已删除。)编辑:感谢sepp2k指出了我的意图。这比我戴着哈斯凯尔彩色眼镜摸索更迫切 下面是一个快速解决方案:
result = (if x > 0 then [3] else []) ++
(if y > 0 then [5] else []) ++
(if x < a then [7] else []) ++
(if y < b then [9] else [])
result=(如果x>0,则[3]否则[])++
(如果y>0,则[5]否则[])++
(如果x
(删除旧答案。)三件事:
if
表达式中使用let
,但在中或在do
块中,它需要后跟。无论哪种方式,使用您刚刚绑定的名称的表达式都需要在相同的中,如果。也就是说,你可以做:
if x > 0
then let a = 42 in a+x
else 23
但不是
if x > 0
then let a = 42 in ()
else let a = 23 in ()
print a
let
更改现有变量的值。事实上,你永远不能改变一个变量的值=
的右侧使用=
的左侧绑定的名称,它将递归地引用自身,而不是以前的任何绑定。换句话说,让x=x+1
引起无限递归,它不会将x
的值增加1foo :: Integer -> Integer -> [Integer]
foo a b = do
let result = []
let Coord x y = boo a b
if x > 0
let result = result ++ [3]
if y > 0
let result = result ++ [5]
if x < a
let result = result ++ [7]
if y < b
let result = result ++ [9]
result
let result1 = if x > 0 then [3] else []
let result2 = if y > 0 then result1 ++ [5] else result1
let result3 = if x < a then result2 ++ [7] else result2
if y < b then result3 ++ [9] else result3
让result1=如果x>0,那么[3]else[]
让result2=如果y>0,则result1++[5]否则result1
设result3=如果x
请注意,从性能角度来看,在末尾使用++
进行追加通常不是一个好主意,而不是使用:
,然后在末尾使用反转。三件事:
您可以在if
表达式中使用let
,但在中或在do
块中,它需要后跟。无论哪种方式,使用您刚刚绑定的名称的表达式都需要在相同的中,如果。也就是说,你可以做:
if x > 0
then let a = 42 in a+x
else 23
但不是
if x > 0
then let a = 42 in ()
else let a = 23 in ()
print a
不能使用let
更改现有变量的值。事实上,你永远不能改变一个变量的值
如果在=
的右侧使用=
的左侧绑定的名称,它将递归地引用自身,而不是以前的任何绑定。换句话说,让x=x+1
引起无限递归,它不会将x
的值增加1
要想做您想做的事情,您需要将代码重组为如下内容:
foo :: Integer -> Integer -> [Integer]
foo a b = do
let result = []
let Coord x y = boo a b
if x > 0
let result = result ++ [3]
if y > 0
let result = result ++ [5]
if x < a
let result = result ++ [7]
if y < b
let result = result ++ [9]
result
let result1 = if x > 0 then [3] else []
let result2 = if y > 0 then result1 ++ [5] else result1
let result3 = if x < a then result2 ++ [7] else result2
if y < b then result3 ++ [9] else result3
让result1=如果x>0,那么[3]else[]
让result2=如果y>0,则result1++[5]否则result1
设result3=如果x
请注意,从性能角度来看,在末尾使用++
进行追加通常不是一个好主意,而不是使用:
,然后在末尾使用反转列表。如果使用的话,您认为的方式也有问题。在Haskell中,如果
是一个表达式,即它的计算结果为一个值。因此,它必须始终伴有else
分支。马塞洛的例子应该澄清这一点。如果您想要命令式语言中的If
语句,那么您就需要Control.Monad.when
或Control.Monad。在Haskell中,如果
是一个表达式,即它的计算结果为一个值。因此,它必须始终伴有else
分支。马塞洛的例子应该澄清这一点。如果您希望在命令式语言中使用类似于If
语句的语句,那么您就有了Control.Monad.when
或Control.Monad。不幸的是,除非您的代码有很多地方出错。第一个问题是顶行的do
:您没有使用任何monad,因此您根本不应该使用它。代码的其余部分试图以命令式的方式工作,但这(毫不奇怪)在Haskell中不起作用。在Haskell中,每个表达式都需要有一个结果;因此,所有if语句的格式必须为<代码>if。。。然后。。。否则…
。同样,每个let绑定的形式必须是let。。。在…
;无法更改变量的值,因此如果您在
中取消了,则不会发生任何事情。正因为如此,如果可以执行,每一行都会尝试创建一个列表,该列表由所有元素组成,最后有一个三,换句话说,一个自引用列表!(这种事情的典型例子是let one=1:ones in one
,创建一个尾部为自身的列表,因此只包含1
s。)
现在的问题是,你的函数想做什么?您有四个布尔条件,并且希望为每个条件向列表中添加不同的元素。你可以用很多方法来写这个。一种方法是
foo :: Integer -> Integer -> Integer
foo a b = let Coord x y = boo a b
checkAdd cond elem = if cond then (elem :) else id
in foldr (uncurry checkAdd) []
[(x > 0, 3), (y > 0, 5), (x > a, 7), (y > b, 9)]
首先,我们调用boo
并查看结果。然后我们定义一个checkAdd
函数,其类型为checkAdd::Bool->a->([a]->[a])