Haskell使用带卫兵的可能吗?

时间:2017-10-23 11:23:53

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

我试图在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"语法实现我想要的?

感谢您的帮助

2 个答案:

答案 0 :(得分:8)

这是可行的,但请记住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具有相同的值:是故意的,还是代码只是一个示例?)

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

答案 1 :(得分:5)

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

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