タグ

ブックマーク / fumieval.hatenablog.com (11)

  • 自動printfデバッグ - モナドとわたしとコモナド

    関数をデバッグするために、引数と戻り値をそれぞれ表示するというのを誰しもやったことがあると思う。今回はそれを自動化するからくりをHaskellで実装してみる。 目標となるのは、関数が与えられたとき、その引数と結果をターミナルに出力する関数に変換する高階関数、probe :: Traceable a => String -> a -> aである。 testDelay :: Double -> Double -> IO () testDelay dur dur' = threadDelay $ round $ (dur + dur') * 1000000 *Probe> probe "testDelay" testDelay 1 2 testDelay 1.0 2.0: () これは型クラスを活用すればお茶の子さいさいである。以下のように型によって挙動を切り替える関数withTraceData

    自動printfデバッグ - モナドとわたしとコモナド
    rydot
    rydot 2021/08/02
  • 快速のExtensible effects - モナドとわたしとコモナド

    extensibleは拡張可能レコードだけでなく拡張可能作用(extensible effects)も用意している。拡張可能作用は一時期Haskell界隈で話題になったものの、今では人気も下火になってしまった。新しいバージョンをリリースした今、拡張可能作用の動機と使い方について改めて紹介しよう。 難行の一次関数 Haskellでモナドをカスタマイズする方法としては、transformersのモナド変換子がよく使われている。モナド変換子は、モナドをパラメータとして取り、新たな能力を付与したモナドにする構造だ。例えば、StateT sはモナド変換子の一つである。任意のアクションm aはliftを使ってStateT s m aに変換できる。 newtype StateT s m a = StateT { runStateT :: s -> m (a, s) } 他にもReaderT, Write

    快速のExtensible effects - モナドとわたしとコモナド
  • GHC 8.0.1/base-4.9.0.0の新機能まとめ - モナドとわたしとコモナド

    GHC 8.0.1は、最上位の桁が変わるだけあって、かなり新しい機能が追加されている。 base-4.9.0.0 めっちゃインスタンスが増えた ghc/changelog.md at ghc-8.0 · ghc/ghc · GitHubを参照。あるべきインスタンスが存在することにより、孤児インスタンスを定義する必要がなくなるため、ぐっとストレスが減る。Monoid a => Monad ((,) a)、Traversable ZipListなど、いくつかは私がやった。 Semigroup ついにData.Semigroupが追加された。将来的にはこれはモノイドのスーパークラスになる。この変更によって、よりリーズナブルな定義ができるということも少なくないはずだ。 ベーシックな型が充実 Compose, Product, Sum, NonEmptyなど、決して利用頻度が高くないとはいえ基礎的か

    GHC 8.0.1/base-4.9.0.0の新機能まとめ - モナドとわたしとコモナド
  • 関数型プログラミングとオブジェクト指向の抜き差し可能な関係について整理して考える - モナドとわたしとコモナド

    Googleで適当に検索すると とズラリと出てくる。 オブジェクト指向 v.s. 関数型プログラミング 関数型とオブジェクト指向という一見相反するプログラミングパラダイムの併用について理解した プログラマが知るべき97のこと/関数型プログラミングを学ぶことの重要性 新人プログラマに知っておいてもらいたい人類がオブジェクト指向を手に入れるまでの軌跡 関数型プログラミングとオブジェクト指向の抜き差しならない関係について整理して考える とそれなりに参考になりそうな情報はあるものの、無駄に複雑化されたオブジェクト指向をストローマンにするような記事ばかり(それだけ今までのオブジェクト指向にみんなうんざりさせられているのだろう)で、そろそろきちんと自分自身「関数型プログラミングとオブジェクト指向の切り離され方」についてはっきりさせておきたい、と考え、概念整理した結論を書きます。 まず端的な結論 結論を

    関数型プログラミングとオブジェクト指向の抜き差し可能な関係について整理して考える - モナドとわたしとコモナド
  • 継続渡しなHaskellライフ - モナドとわたしとコモナド

    CPS(Continuation passing style, 継続渡しスタイル)は、関数型プログラミングにおけるプログラムの書き方の一つである。CPSを導入する簡単な例をいくつか紹介しよう。 まず、入力された数値が3の倍数かどうかを判定するプログラムを作ってみよう。 foo :: IO Bool foo = do n <- readLn :: IO Int return (n `mod` 3 == 0) ここで「CPS変換」なる儀式を行うと…こうなる! foo' :: (Bool -> IO r) -> IO r foo' cont = do n <- readLn :: IO Int cont (n `mod` 3 == 0) 「なにこれ、returnを置き換えただけじゃねえか!意味わかんねー!」という声が聞こえてきそうだが、もう少し考えてみよう。 3の倍数が入力されたらFizz、5の

    継続渡しなHaskellライフ - モナドとわたしとコモナド
  • モナドとはモナドである - モナドとわたしとコモナド

    この記事を読む前に、絶対に理解出来ないモナドチュートリアルに一度目を通してみてほしい。モナドを理解していく上で、とても重要なことが書かれている。 改めて言おう、モナドはモナドだ。コンテナだとかプログラマブルセミコロンだという説明では、モナドのすべてを正確に表せるとは言い難い。では、モナドを過不足なく説明できる、モナド以外の言葉はあるのか? 実は、モナドを表現し、かつモナドで表現される言葉は存在する。その一つは手続きである。手続き型言語の「手続き」だ。 手続きとは何か 手続きは結果を持つ おおよそすべての手続きは何らかの結果を持つ。Haskellの()、C言語のvoid、PythonのNone、Rubyのnilなども結果の一種だ。結果が出ないとしたら、そのプログラムは停止しないか、途中で異常終了するだろう。 手続きには最小単位が存在する 処理系が扱っている以上、手続きが際限なく分解できるとい

    モナドとはモナドである - モナドとわたしとコモナド
  • モナドの六つの系統[Functor x Functor] - モナドとわたしとコモナド

    モナドは「アクション」を表す抽象的な構造である。モナドは、Haskellにさまざまな概念に対する記述能力をもたらす。 モナドの基礎 return :: a -> m a: 純粋な値をモナドで包む。 m >>= f :: m a -> (a -> m b) -> m b: モナドmに包まれた値をfに渡し、その結果として現れたモナドを結合する。 固有アクション: それぞれのモナドに固有の方法でモナドを生み出す。 実行: モナドに包まれた値を、より根源的な形に還元する。 モナド則 モナドに以下の三つの制約を課すことによって、最低限度の記述能力を保証している。 return a >>= k == k a m >>= return == m m >>= (\x -> k x >>= h) == (m >>= k) >>= h より強い制約は、より強い力を生み出す。 モナドの分類 モナドは、以下の6つ

    モナドの六つの系統[Functor x Functor] - モナドとわたしとコモナド
  • Indexed Monadの世界 - モナドとわたしとコモナド

    もっと、モナドの力を引き出したくはないか? え?アクションの前後で型を変えたい?いやいやいや、モナドは自己関手の圏上の単なるモノイドだよ、そんなことができ…る…!?えっ、できるの…マジで…? できる。そう、Haskellならね。 {-# LANGUAGE QuasiQuotes #-} import Control.Monad.Indexed.State import Control.Monad.Indexed import Language.Haskell.IndexedDo hoge :: IxState Int [Int] () hoge = [ido|do imodify (*10) imodify show imodify reverse imodify (++"123") imodify $ map fromEnum |] *ghci> runIxState hoge 42 (

    Indexed Monadの世界 - モナドとわたしとコモナド
  • Freeモナドを超えた!?operationalモナドを使ってみよう - モナドとわたしとコモナド

    限定版IOみたいなモナドを簡単に作れたら、コードが分離できるしテストもしやすくなるのになあ… 数か月前なら、 それ、Freeモナド*1でできるよ! と返されるだろう。だが今は違う。Freeモナドよりも簡単にモナドを作れるモナド、Operationalモナドがあるのだ。 Freeモナドについて復習しよう。FreeモナドはFunctorを基にMonadを作れる構造であり、Functorで自分自身を包むことによってモナドの力を得ている*2。FunctorそのものはDeriveFunctor拡張を使って簡単に作れる。 {-# LANGUAGE DeriveFunctor #-} import Control.Monad.Free data CharIO a = PutCh Char a | GetCh (Char -> a) | LiftIO (IO a) deriving Functor put

    Freeモナドを超えた!?operationalモナドを使ってみよう - モナドとわたしとコモナド
  • Freeモナドでゲームを作ろう!第1回: Gameモナドの基本 - モナドとわたしとコモナド

    連載目次 第0回: 概要 第1回: Gameモナドの基 (この記事) free-gameを使う さて、みなさん、free-gameはインストールしましたか?まだの型方も、もうインストールした方も、日free-gameを更新したのでcabal update && cabal install free-gameしましょう。 2013/5/6: free-game 0.9.3をリリースし、内容も改訂しました。必ずcabal update && cabal install free-gameしてください。 free-gameは、Gameモナドという独自のモナドによってGUIの抽象化を実現しています。GameはFreeモナドによって生成されたモナドであり、元は単なるFunctorです(これが何を意味するかは、連載の中で明らかにしていきます)。 今回は、実際にプログラムを組みながら、どのようにして

    Freeモナドでゲームを作ろう!第1回: Gameモナドの基本 - モナドとわたしとコモナド
  • そろそろFreeモナドに関して一言いっとくか - モナドとわたしとコモナド

    Freeモナドはすごい。 Haskellを書いていて、「特殊化された処理を記述するモナドが簡単に作れたら便利だろうなー」と思ったことはないだろうか?簡単に作れるのである、そう、Haskellならね。 これが、純粋なFreeモナドの定義である。 data Free f a = Pure a | Free (f (Free f a)) instance Functor f => Monad (Free f) where return = Pure Pure a >>= k = k a Free fm >>= k = Free (fmap (>>=k) fm) (Functor、Applicativeのインスタンス宣言は自明なので省略) 与えられたFunctorをお互いに埋め込み合っている、という漠然とした印象で、何が嬉しいのかよくわからないかもしれない。だが、この単純さこそFreeモナドの便利

    そろそろFreeモナドに関して一言いっとくか - モナドとわたしとコモナド
  • 1