let
は、単一の不変の値を使用して新しいローカル変数を導入し、そしてそれはどんな周囲の定義よりも多くのローカルスコープを持っている、よう:
*Main> (let length = 2 in show length) ++ ' ':show (length "Hello")
"2 5"
ここでは最初のlength
の値は2ですが、その有効範囲は角かっこのローカルです。角括弧の外側では、length
は、それが常に意味するものを意味します。何も編集されていないだけで、異なるスコープ内の別のものと同じ名前を持つローカル変数が導入されました。ブラケットを省略し、それがlength
数や機能を作ってみることによりGHCiのは怒ってみましょう:
*Main> let length = 2 in show length ++ ' ':show (length "Hello")
<interactive>:1:14:
No instance for (Num ([Char] -> a0))
arising from the literal `2'
Possible fix: add an instance declaration for (Num ([Char] -> a0))
In the expression: 2
In an equation for `length': length = 2
In the expression:
let length = 2 in show length ++ ' ' : show (length "Hello")
<interactive>:1:19:
No instance for (Show ([Char] -> a0))
arising from a use of `show'
Possible fix: add an instance declaration for (Show ([Char] -> a0))
In the first argument of `(++)', namely `show length'
In the expression: show length ++ ' ' : show (length "Hello")
In the expression:
let length = 2 in show length ++ ' ' : show (length "Hello")
そして、ここではあなたの例です:
*Main> let e = exp 1 in show e ++ " " ++ let e = 2 in show e
"2.718281828459045 2"
私はスコープを強調するためにブラケットを追加します:
*Main> let e = exp 1 in (show e ++ " " ++ (let e = 2 in (show e)))
"2.718281828459045 2"
最初のe
は編集されずに非表示になっています。参照透明度は保持されますが、それは難しいため間違いなく練習です。
testdo = do
let e = exp 1
print e
let e = 2
print e
今、私はそれが破壊のような非常に多く見える認めざるを得ない:
は今密かに対話プロンプトは、それでは、その見てみましょう、ビットIOモナドで一つの大きなdo
ブロックのようなものです参照透明性が、それはあまりにもないように、これが見えることに注意してください:どのような意味で今
testWrite = do
writeFile "test.txt" "Hello Mum"
xs <- readFile "test.txt"
print xs
writeFile "test.txt" "Yo all"
xs <- readFile "test.txt"
print xs
は、我々は参照透明性を持っていますか? xs
は明らかに2つの異なる文字列を参照しています。さて、これは実際にはdo
表記とは何ですか?
testWrite = writeFile "test.txt" "Hello Mum"
>> readFile "test.txt"
>>= (\xs -> print xs
>> writeFile "test.txt" "Yo all"
>> readFile "test.txt"
>>= (\xs -> print xs))
ここでは、割り当てのように見えるのはもう一度ローカルスコープになっていることが分かります。あなたはおそらく幸せです
increment :: [Int] -> [Int]
increment = \x -> map (\x -> x+1) x
これは同じことをしています。割り当てのように見えるもの
概要
は、新しいローカルスコープの単なる紹介です。 Phew。これをたくさん使うと、あなたのコードが何を意味するのかが非常に不明瞭になります。
@ jberryman 2)と3)はすでに[私の解答]の後半でカバーされていました(http://stackoverflow.com/questions/13545580/functional-purity-using-let-in-haskell/13545731#13545731 )以下のdbauppの同様のコメントに従います。 – AndrewC