lef*_*out 10
=意味着被定义为相等.即,如果我写的话
x = 5
Run Code Online (Sandbox Code Playgroud)
在文件的某个地方,我可以在任何其他点(在同一范围内)替换5,x反之亦然 - 它们是相同的.(并且将始终保持不变.)然而,定义也可以引用您绑定它的名称,以提供递归计算,如
fibonacci :: [Integer]
fibonacci = 0 : 1 : zipWith (+) fibs (tail fibonacci)
Run Code Online (Sandbox Code Playgroud)
在这种情况下,你仍然可以在任何时候替代fibonacci用0 : 1 : zipWith (+) fibs (tail fibonacci),但你当然需要无限重复这一过程.
甲=定义可以站在或者在顶层,即,在模块中的线自身,或内let或where块:
silly :: Integer -> Integer
silly x = y
where y = let z = x + 1
in z - 1
Run Code Online (Sandbox Code Playgroud)
这里silly是顶级绑定(带有函数参数),y是where绑定,z是let绑定.
<-装置基本上定义为结果的,这意味着一个monadic计算的结果.它通常位于一个do区块中,例如:
main :: IO ()
main = do
putStrLn "Enter your name, please"
userName <- getLine
putStrLn $ "Hello, " ++ userName
Run Code Online (Sandbox Code Playgroud)
请注意,这是非常不同的
main = do
putStrLn "Enter your name, please"
let userName' = getLine
putStrLn $ "Hello, " ++ userName' -- error here
Run Code Online (Sandbox Code Playgroud)
这样做不会定义userName为用户输入的字符串,而是作为请求输入字符串的操作.userName是String,但是userName' :: IO String.
<- 也用于列表推导:
squareNums :: [Integer]
squareNums = [x^2 | x <- [0..]]
Run Code Online (Sandbox Code Playgroud)
看起来这有点不同userName <- getLine,但实际上它做同样的事情,只是在一个不同的monad(列表而不是IO).事实上,我也可以写为
squareNums = do
x <- [0..]
return $ x^2
Run Code Online (Sandbox Code Playgroud)
还有第三种用途<-是真正不同的:图案防护,但这些并不常见.
<=只是一个库函数(以中缀运算符的形式).对于你在Haskell中遇到的大多数其他符号"语法"也是如此.你可以问Hayoo关于这样的运营商,它会告诉你,<=是的定义Data.Ord模块,并简单地越少-即有或等于比较操作.
您也可以自己定义这些操作符 - 如果它不在标准库中,我可以轻松定义
(<=) :: Ord a => a -> a -> Bool
x <= y = not $ x > y
Run Code Online (Sandbox Code Playgroud)
顺便提一下,=>签名中的内容完全不同 - 这也是内置语法.本周还有一个问题.
=是一种约束力.它将名称绑定到值/表达式.您可以将它用于顶级绑定,let块和块中.
myfun x = let y = x + 1
in z y
where z n = n * n
Run Code Online (Sandbox Code Playgroud)
<-是一种提取物.它是do符号的一部分,并引入了一个与monad内容绑定的名称.
main = do
name <- getLine
putStrLn ("Hello, " ++ name)
Run Code Online (Sandbox Code Playgroud)
<=是Cmp类型类中定义的不太相等的运算符.
message x = if x < 18 then "No, you can't vote." else "Go ahead."
Run Code Online (Sandbox Code Playgroud)