Upgrade to Pro — share decks privately, control downloads, hide ads and more …

純粋関数型言語では副作用をどう扱うのか / Side Effects in Purely Functional Languages

tipo159
June 06, 2017

純粋関数型言語では副作用をどう扱うのか / Side Effects in Purely Functional Languages

純粋関数型言語での副作用の扱い方としてStream-based I/OとMonadic I/Oを、純粋関数型AltJS(PureScriptとElm)での副作用の扱い方を紹介しています。
We Are JavaScripters! 8th
WeJS

tipo159

June 06, 2017
Tweet

More Decks by tipo159

Other Decks in Programming

Transcript

  1. アウトライン 1. 純粋関数型言語での副作用の扱い方 ▻ Stream-based I/O ▻ Monadic I/O 2.

    純粋関数型AltJSでの副作用の扱い方 ▻ PureScript ▻ Elm 3. まとめ 3
  2. 6 Haskellプログラム [Response] [Request] Stream-based I/Oの概念図 (Haskell 1.0) main ::

    [Response] -> [Request] 副作用をプログラムの入出力として扱う
  3. main :: [Response] -> [Request] data Request = ReadFile Name

    | WriteFile Name String | … data Response = Success | Str String | Failure IOError | … Stream-based I/Oの定義抜粋 7
  4. main :: Dialogue main ~(Success : ~((Str userInput) : ~(Success

    : ~(r4 : _)))) = [ AppendChan stdout "please type a filename\n", ReadChan stdin, AppendChan stdout name, ReadFile name, AppendChan stdout (case r4 of Str contents -> contents Failure ioerr -> "can’t open file") ] where (name : _) = lines userInput Stream-based I/Oのプログラム例 8 Requests: [AppendChan …, ReadChan …, AppendChan …, ReadFile …, AppendChan …] Response: [Success, Str userInput, Success, Str contents or Failure ioerr, Success]
  5. 10 IO t Monadic I/Oの概念図 (Haskell 98) main:: IO ()

    type IO t = World -> (t, World) result :: t タイプ(IO t)の値は、Action 実行されるとタイプtの結果を返す前にIOを行う
  6. 11 Actionはファーストクラスオブジェクト type IO t = World -> (t, World)

    ▰ Actionはファーストクラスオブジェクト ▻ 複数Actionの合成が可能 ▰ Actionの評価(Evaluating)は作用なし ▻ 遅延評価等の評価順序とは違う概念 ▰ Actionの実行(Performing)は作用あり
  7. 12 Action合成の例 putChar getChar Char () getChar :: IO Char

    putChar :: Char -> IO () getCharとputCharを合成
  8. 13 Bindコンビネータ(>>=) [1 / 3] putChar getChar Char () (>>=)

    :: IO a -> (a -> IO b) -> IO b echo :: IO () Echo = getChar >> = putChar
  9. 15 Bindコンビネータ(>>=) [3 / 3] ▰ 合成Action a >>= \x

    -> bを実行すると ▻ aを実行して結果rを提供(yield) ▻ 関数\x -> bをrに適用(apply) ▻ b{x <- r}の結果Actionを実行 ▻ 結果vを返却 b a r v x
  10. 18 PureScript Monadic I/Oを採用 HaskellのMonadと違い、副作用の対象を明記 main:: forall e. Eff (fs

    :: FS, console:: CONSOLE | e) Unit この例ではmainはファイルシステムを使用し、 コンソールにメッセージを出力する
  11. 19 Elm The Elm Architectureに基づき、副作用はElm Runtimeで実施 ▰ The Elm ArchitectureはWebフレームワークの様なもの

    ▰ アプリケーションの状態をModelで、Modelの更新方法を Updateで、モデルの表示をViewで定義する ▰ Stream-based I/OのRequestに対応するCmdと、Responseに 対応するSubで副作用のある処理を管理
  12. 23 まとめ ▰ 純粋関数型言語 ▻ Stream-based I/O: 副作用をプログラムの入出力に ▻ Monadic

    I/O: Actionが値となるモナドを使用 ▰ 純粋関数型AltJS ▻ PureScript: モナドを使用 ▻ Elm: Stream-based I/Oに類似したCmd/Subを使用