Haskellの純粋なものと不純なものの違いは何ですか?haskellでIOを行う場合、純粋なアイテムと不純なアイテムを別々に保つとはどういう意味ですか?
3 に答える
基本的に、「不純なセクション」にできるだけ少ないコードを保持する必要があります。IOモナドで記述されたコードは、永久に不安定に汚染されています。シグニチャを持つ関数IO Int
はIOモナドで整数を返しますが、その上に核ミサイルを月に送ることができます。コードのすべての行を調べなければ、知る方法はありません。
たとえば、文字列を受け取り、それに「、dude」を追加するプログラムを作成するとします。
main = do
line <- getLine
putStrLn $ line ++ ", dude"
コードの一部は副作用があるため、IOモナドに含める必要があります。これには、getLineとputStrLnが含まれます。ただし、2つの文字列を組み合わせるとそうではありません。
main = do
line <- getLine
putStrLn $ addDude line
addDude input = input ++ ", dude"
addDudeの署名は、それが純粋であることを示していますString -> String
。いいえ、IO
ここではありません。これは、addDudeが少なくともそのように動作すると想定できることを意味します。1つの文字列を受け取り、1つの文字列を返します。それが副作用を持つことは不可能です。月を爆破することは不可能です。
純度とは、単に副作用(ディスクからの読み取り、ロボットアームの移動など)を引き起こさないことを意味します。
純粋な関数を不純な関数から分離することは、コードが何をするかについてもっと知ることができることを意味します。たとえば、と言うと、そのタイプ( )によって、2つの数値を取り、3番目の数値を生成するだけであることが1 + 2
確実にわかります。Int -> Int -> Int
タイプがInt -> Int -> IO Int
の場合、2つの数値を加算するたびにロボットアームが移動する可能性があります。
Haskellの基本の良い出発点はここにあります:http: //learnyouahaskell.com/introduction#so-whats-haskell
Haskellのすべてが純粋です。あなたが読んでいるのは、IOモンダッドの内部と外部のコードに関するものである可能性があります。IOモナドに何かを入れると、それが「エスケープ」することはありません。IOモナドにとどまる必要があります。したがって、IOモナドはコードに「侵入」する傾向があります。IOを返すものがある場合、それを呼び出すコードはIOも返す必要があります。したがって、IOモナドは、プログラムの可能な限り最上位で、必要な場合にのみ使用し、純粋な計算の部分を純粋関数に分離するのが最善です。