=,< - ,< =在haskell之间的区别是什么?

时间:2016-08-25 10:06:38

标签: haskell syntax

我们经常在haskell中看到=<-<=。它们之间的区别是什么?

2 个答案:

答案 0 :(得分:10)

  • =表示定义为相等。即,如果我写

    x = 5
    

    在文件的某个地方,我可以在任何其他点(在同一范围内)将5替换为x,反之亦然 - 它们是相同的。 (并且将始终保持不变。)然而,定义也可以引用您绑定它的名称,以提供递归计算,如

    fibonacci :: [Integer]
    fibonacci = 0 : 1 : zipWith (+) fibs (tail fibonacci)
    

    在这种情况下,您仍然可以随时用fibonacci替换0 : 1 : zipWith (+) fibs (tail fibonacci),但当然您需要无限重复此过程。
    =定义既可以位于顶层,也可以位于模块中的一行,也可以位于letwhere块中:

    silly :: Integer -> Integer
    silly x = y
     where y = let z = x + 1
               in z - 1
    

    此处,silly是顶级绑定(带有函数参数),ywhere绑定,zlet结合。

  • <-表示定义为结果,表示monadic计算的结果。它通常位于do块中,例如:

    main :: IO ()
    main = do
       putStrLn "Enter your name, please"
       userName <- getLine
       putStrLn $ "Hello, " ++ userName
    

    请注意,这与

    非常不同
    main = do
       putStrLn "Enter your name, please"
       let userName' = getLine
       putStrLn $ "Hello, " ++ userName'  -- error here
    

    这样做不会将userName定义为用户输入的字符串,而是定义请求输入字符串的操作userNameString,但userName' :: IO String

    <-也用于列表推导:

    squareNums :: [Integer]
    squareNums = [x^2 | x <- [0..]]
    

    这似乎与userName <- getLine有所不同,但实际上它只是在不同的monad(列表而不是IO)中执行相同的操作。事实上我也可以把它写成

    squareNums = do
        x <- [0..]
        return $ x^2
    

    还有<-的第三种用法,它实际上是不同的:pattern guards,但这些并不常见。

  • <=只是一个库函数(以中缀运算符的形式)。对于你在Haskell中遇到的大多数其他符号“语法”也是如此。您可以ask Hayoo关于此类运算符,它会告诉您<=defined in the Data.Ord module,并且只是比较小或相等的比较运算符。
    您也可以自己定义这些操作符 - 如果它不在标准库中,我可以轻松定义

    (<=) :: Ord a => a -> a -> Bool
    x <= y = not $ x > y
    

    顺便提一下,签名中的=>是完全不同的 - 这又是内置语法。本周还有question about that

答案 1 :(得分:5)

=是一种约束力。它将名称绑定到值/表达式。您可以将它用于顶级绑定,let块和块。

myfun x = let y = x + 1
          in z y
  where z n = n * n

<-是一个monadic提取。它是do表示法的一部分,并引入了一个与monad内容绑定的名称。

main = do
  name <- getLine
  putStrLn ("Hello, " ++ name)

<=Cmp类型类中定义的次要或不相等的运算符。

message x = if x < 18 then "No, you can't vote." else "Go ahead."