此 'where' 子句的正确 Haskell 语法是什么?
what is the correct Haskell syntax for this 'where' clause?
此语法的适当更正是什么?是白space的问题吗?我复制了 LYAH, also tried other variations gleaned from .
中示例中使用的 whitespace
我确定有更好的方法来编写此代码,但我还不太擅长自由代码。我是 新手 级别,正在尝试掌握非常基本的语法知识,这些语法知识通过大量的 codewars 练习继续让我感到困惑。
import Data.List (findIndices)
basicOp :: Char -> Int -> Int -> Int
basicOp x y z = (operations !! (op x)) y z
where op x = head $ findIndices (== x) "+-*/" :: Char -> Int
operations = [(+), (-), (*), (div)] :: [(Int -> Int -> Int)]
当我像这样写一个函数并引用另外两个函数时它起作用了。
import Data.List (findIndices)
operations :: [(Int -> Int -> Int)]
operations = [(+), (-), (*), (div)]
op :: Char -> Int
op x = head $ findIndices (== x) "+-*/"
basicOp :: Char -> Int -> Int -> Int
basicOp x y z = (operations !! (op x)) y z
带有 where 子句的代码 returns 这些错误:
codewars.hs:103:34: error:
• Couldn't match expected type ‘Int’ with actual type ‘Char -> Int’
• Probable cause: ‘op’ is applied to too few arguments
In the second argument of ‘(!!)’, namely ‘(op x)’
In the expression: (operations !! (op x)) y z
In an equation for ‘basicOp’:
basicOp x y z
= (operations !! (op x)) y z
where
op x = head $ findIndices (== x) "+-*/" :: Char -> Int
operations = [(+), ....] :: [(Int -> Int -> Int)]
|
103 | basicOp x y z = (operations !! (op x)) y z
| ^^^^
codewars.hs:104:18: error:
• Couldn't match expected type ‘Char -> Int’ with actual type ‘Int’
• Possible cause: ‘($)’ is applied to too many arguments
In the expression: head $ findIndices (== x) "+-*/" :: Char -> Int
In an equation for ‘op’:
op x = head $ findIndices (== x) "+-*/" :: Char -> Int
In an equation for ‘basicOp’:
basicOp x y z
= (operations !! (op x)) y z
where
op x = head $ findIndices (== x) "+-*/" :: Char -> Int
operations = [(+), ....] :: [(Int -> Int -> Int)]
|
104 | where op x = head $ findIndices (== x) "+-*/" :: Char -> Int
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
我最初的尝试可能更容易阅读,但这只是一个尝试使用更多我还不熟悉的 Haskell 结构的练习。
basicOp :: Char -> Int -> Int -> Int
basicOp oper x y
| oper == '+' = (+) x y
| oper == '-' = (-) x y
| oper == '*' = (*) x y
| oper == '/' = (div) x y
根据@DanielWagner 的评论,这已改进为:
basicOp c = case c of
'+' -> (+)
'-' -> (-)
'*' -> (*)
'/' -> div
op x
表达式的主体类型是 Int
,而不是 Char -> Int
。您还应该将 operations
与 op
放在同一列,因此:
basicOp :: Char -> Int -> Int -> Int
basicOp x y z = (operations !! (op x)) y z
where op x = head $ findIndices (== x) "+-*/" :: Int
operations = [(+), (-), (*), (div)] :: [(Int -> Int -> Int)]
但是类型不是必须的,你可以简化为:
basicOp :: Char -> Int -> Int -> Int
basicOp x = (operations !! op x)
where op x = head $ findIndices (== x) "+-*/"
operations = [(+), (-), (*), (div)]
并与 lookup :: Eq a => a -> [(a, b)] -> Maybe b
一起工作:
basicOp :: Char -> Int -> Int -> Int
basicOp x | Just y <- lookup x operations = y
| otherwise = …
where operations = [('+', (+)), ('-', (-)), ('*', (*)), ('/', div)]
其中 …
是一个表达式,如果未找到该键,则对其求值
哦,删除 op
和 operations
的类型声明有效。
我认为有时将类型声明“内联”是可以的(甚至有帮助)。
basicOp :: Char -> Int -> Int -> Int
basicOp x y z = (operations !! (op x)) y z
where
op x = head $ findIndices (== x) "+-*/"
operations = [(+), (-), (*), (div)]
请注意,您可以为函数本身提供类型,或者在单独的行上
basicOp :: Char -> Int -> Int -> Int
basicOp x y z = (operations !! (op x)) y z
where
op :: Char -> Int
op x = head $ findIndices (== x) "+-*/"
operations = [(+), (-), (*), (div)] :: [(Int -> Int -> Int)]
或通过提供明确的 lambda 表达式作为 op
.
的值
basicOp :: Char -> Int -> Int -> Int
basicOp x y z = (operations !! (op x)) y z
where op = (\x -> head $ findIndices (== x) "+-*/") :: Char -> Int
operations = [(+), (-), (*), (div)] :: [(Int -> Int -> Int)]
此语法的适当更正是什么?是白space的问题吗?我复制了 LYAH, also tried other variations gleaned from
我确定有更好的方法来编写此代码,但我还不太擅长自由代码。我是 新手 级别,正在尝试掌握非常基本的语法知识,这些语法知识通过大量的 codewars 练习继续让我感到困惑。
import Data.List (findIndices)
basicOp :: Char -> Int -> Int -> Int
basicOp x y z = (operations !! (op x)) y z
where op x = head $ findIndices (== x) "+-*/" :: Char -> Int
operations = [(+), (-), (*), (div)] :: [(Int -> Int -> Int)]
当我像这样写一个函数并引用另外两个函数时它起作用了。
import Data.List (findIndices)
operations :: [(Int -> Int -> Int)]
operations = [(+), (-), (*), (div)]
op :: Char -> Int
op x = head $ findIndices (== x) "+-*/"
basicOp :: Char -> Int -> Int -> Int
basicOp x y z = (operations !! (op x)) y z
带有 where 子句的代码 returns 这些错误:
codewars.hs:103:34: error:
• Couldn't match expected type ‘Int’ with actual type ‘Char -> Int’
• Probable cause: ‘op’ is applied to too few arguments
In the second argument of ‘(!!)’, namely ‘(op x)’
In the expression: (operations !! (op x)) y z
In an equation for ‘basicOp’:
basicOp x y z
= (operations !! (op x)) y z
where
op x = head $ findIndices (== x) "+-*/" :: Char -> Int
operations = [(+), ....] :: [(Int -> Int -> Int)]
|
103 | basicOp x y z = (operations !! (op x)) y z
| ^^^^
codewars.hs:104:18: error:
• Couldn't match expected type ‘Char -> Int’ with actual type ‘Int’
• Possible cause: ‘($)’ is applied to too many arguments
In the expression: head $ findIndices (== x) "+-*/" :: Char -> Int
In an equation for ‘op’:
op x = head $ findIndices (== x) "+-*/" :: Char -> Int
In an equation for ‘basicOp’:
basicOp x y z
= (operations !! (op x)) y z
where
op x = head $ findIndices (== x) "+-*/" :: Char -> Int
operations = [(+), ....] :: [(Int -> Int -> Int)]
|
104 | where op x = head $ findIndices (== x) "+-*/" :: Char -> Int
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
我最初的尝试可能更容易阅读,但这只是一个尝试使用更多我还不熟悉的 Haskell 结构的练习。
basicOp :: Char -> Int -> Int -> Int
basicOp oper x y
| oper == '+' = (+) x y
| oper == '-' = (-) x y
| oper == '*' = (*) x y
| oper == '/' = (div) x y
根据@DanielWagner 的评论,这已改进为:
basicOp c = case c of
'+' -> (+)
'-' -> (-)
'*' -> (*)
'/' -> div
op x
表达式的主体类型是 Int
,而不是 Char -> Int
。您还应该将 operations
与 op
放在同一列,因此:
basicOp :: Char -> Int -> Int -> Int
basicOp x y z = (operations !! (op x)) y z
where op x = head $ findIndices (== x) "+-*/" :: Int
operations = [(+), (-), (*), (div)] :: [(Int -> Int -> Int)]
但是类型不是必须的,你可以简化为:
basicOp :: Char -> Int -> Int -> Int
basicOp x = (operations !! op x)
where op x = head $ findIndices (== x) "+-*/"
operations = [(+), (-), (*), (div)]
并与 lookup :: Eq a => a -> [(a, b)] -> Maybe b
一起工作:
basicOp :: Char -> Int -> Int -> Int
basicOp x | Just y <- lookup x operations = y
| otherwise = …
where operations = [('+', (+)), ('-', (-)), ('*', (*)), ('/', div)]
其中 …
是一个表达式,如果未找到该键,则对其求值
哦,删除 op
和 operations
的类型声明有效。
我认为有时将类型声明“内联”是可以的(甚至有帮助)。
basicOp :: Char -> Int -> Int -> Int
basicOp x y z = (operations !! (op x)) y z
where
op x = head $ findIndices (== x) "+-*/"
operations = [(+), (-), (*), (div)]
请注意,您可以为函数本身提供类型,或者在单独的行上
basicOp :: Char -> Int -> Int -> Int
basicOp x y z = (operations !! (op x)) y z
where
op :: Char -> Int
op x = head $ findIndices (== x) "+-*/"
operations = [(+), (-), (*), (div)] :: [(Int -> Int -> Int)]
或通过提供明确的 lambda 表达式作为 op
.
basicOp :: Char -> Int -> Int -> Int
basicOp x y z = (operations !! (op x)) y z
where op = (\x -> head $ findIndices (== x) "+-*/") :: Char -> Int
operations = [(+), (-), (*), (div)] :: [(Int -> Int -> Int)]