【问题标题】:How to use let with guards in Haskell?如何在 Haskell 中使用 let 和守卫?
【发布时间】:2018-04-03 22:20:54
【问题描述】:

我正在尝试在 Haskell 中执行以下操作:

 someFunction :: [] -> Int
 someFunction list 
 let a
 | length list == 1 = 10
 | otherwise = 0
 b
 | length list == 1 = 10 
 | otherwise = 0
 in findValues (a+b)

因此 a 和 b 的值将取决于守卫中的条件是否满足。这种语法不断给我错误,我不知道为什么。我需要使用 where 子句还是有正确的“let”语法来实现我想要的?

感谢您的帮助

【问题讨论】:

  • 为什么不直接写let a = if length list == 1 then 10 else 0

标签: haskell functional-programming haskell-stack haskell-platform guard-statement


【解决方案1】:

这是可行的,但请记住length list == 1 的效率非常低:它会扫描所有条目以逐个计数,花费 O(N) 时间与 1 进行比较。

相反,请考虑使用case .. of,它可以在恒定时间内检查。

someFunction :: [] -> Int
someFunction list = let
   a = case list of
       [_] -> 10   -- list is of the form [x] for some x
       _   -> 0    -- list is of any other form
   b = case list of
       [_] -> 10
       _   -> 0
   in findValues (a+b)

甚至:

someFunction :: [] -> Int
someFunction list = let
   (a,b) = case list of
       [_] -> (10,10)    -- list is of the form [x] for some x
       _   -> (0 ,0 )    -- list is of any other form
   in findValues (a+b)

(还要注意ab 具有相同的值:这是故意的,还是代码只是一个示例?)

如果可能,我强烈建议避免使用有利于模式匹配的守卫。

【讨论】:

    【解决方案2】:

    这有点难说,但我猜你的意思是

    someFunction :: [] -> Int
    someFunction list =
      let a | length list == 1 = 10
            | otherwise = 0
          b | length list == 1 = 10 
            | otherwise = 0
      in findValues (a+b)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-26
      • 1970-01-01
      • 2020-05-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-22
      • 1970-01-01
      相关资源
      最近更新 更多