用do's

时间:2019-02-09 17:03:38

标签: haskell

因此,我刚刚掌握了Haskell的知识,并陷入了用Do创建嵌套的if-else语句的语法中。 我不确定,如果我应该使用多个Do,还是仅用一个就可以完成全部操作。 我也不确定是否应该使用return语句以及是否需要所有分号。

我尝试添加和删除花括号,return语句,分号,不同的缩进,但不知道还要尝试什么。

我收到类似“•无法将预期的类型'm0(m0 b0)'与实际类型'Int'相匹配的错误     •在“ do”块的stmt中:<-getVal “

  1. 这是我要构建的结构,但它给了我错误。您可以将getVal函数想象为返回整数的任意函数:

    func :: Int -> Int
    func val = do {
       if val < 10
          then do {
              a <- getVal0;
              b <- getVal1;
              if (val+a+b) < 0
                 then return 1
                 else return 2}
          else if val > 10 
              then do {
                 a <- getVal2;
                 b <- getVal3;
                 if (val + a +b) < 0 
                   then return 0
                   else return 1}
          else return 99;     }
    

get val的示例为:

    getVal :: Int
    getVal  = 5

这就是我想要发生的事情:

如果val <10,则从getVal0获得带有2个参数的值a,并从getVal1获得b。然后添加val + a + b,如果该值小于0,则返回1,否则返回2

如果val> 10,则从getVal2获取a,从getVal3获取b。如果val + a + b <0,则返回0,否则返回1。

如果val既不是<10也不是> 10(val = 10),则返回99

感谢您的反馈和帮助!

1 个答案:

答案 0 :(得分:5)

正如评论中已经提到的,您在这里不需要do<-return。这些用于单子代码,但是在这里您定义了一个常规函数-周围没有单子。

因此,我们可以改用let .. in ..。这是一种可能的方法,对原始代码进行较小的更改。

func :: Int -> Int
func val =
   if val < 10 then let
      a = getVal0
      b = getVal1
      in if val + a + b < 0
         then 1
         else 2
   else if val > 10 then let
      a = getVal2
      b = getVal3
      in if val + a + b < 0 
         then 0
         else 1
   else 99

许多Haskellers会考虑将最外面的if变成后卫:

func :: Int -> Int
func val
   | val < 10 = let
      a = getVal0
      b = getVal1
      in if val + a + b < 0
         then 1
         else 2
   | val > 10 = let
      a = getVal2
      b = getVal3
      in if val + a + b < 0 
         then 0
         else 1
   | otherwise = 99