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"
1つ目e
は、編集ではなく非表示になっています。参照透過性は維持されますが、従うのが難しいため、これは間違いなく悪い習慣です。
密かにインタラクティブプロンプトはdo
IOモナドの1つの大きなブロックに少し似ているので、それを見てみましょう。
testdo = do
let e = exp 1
print e
let e = 2
print e
今、私はそれが参照透過性を壊すのと非常によく似ていることを認めなければなりませんが、これもそうであるように見えることを覚えておいてください:
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
これは同じことをしています。
まとめ
割り当てのように見えたのは、新しいローカルスコープの導入だけです。ふぅ。これを頻繁に使用すると、コードの意味が非常に不明確になります。