#FsControl
FsControlというオーバーロードのためのライブラリがある。
これはHaskellの型クラスのような機能を実現する。
詳しい使い方はFSharpPlusのコードを読むと良い。実際の使い方がよく分かる。
今回は、FsControlが標準で提供してくれているCont型を使って限定継続を実装する。
#限定継続
『F#で shift/reset プログラミング。限定継続(風)モナドで四天王問題を解く。 - Bug Catharsis』を参考にさせていただいた。
コードはほぼhttp://www.haskell.org/haskellwiki/MonadCont_done_rightの翻訳である。
#コード
open FsControl.Core.Types
open FsControl.Core.TypeMethods
open FsControl.Core.TypeMethods.Applicative
open FsControl.Core.TypeMethods.Monad
//https://github.com/gmpl/FsControl/blob/master/FsControl.Core/Samples/Haskell.fsx
let inline return' x = Inline.instance Pure x
let inline (>>=) x (f:_->'R) : 'R = Inline.instance (Bind, x) f
type DoNotationBuilder() =
member inline b.Return(x) = return' x
member inline b.Bind(p,rest) = p >>= rest
member b.Let (p,rest) = rest p
member b.ReturnFrom(expr) = expr
let do' = new DoNotationBuilder()
let runCont = Cont.run
let callCC' = Cont.callCC
let inline when' p s = if p then s else return' ()
let inline unless p s = when' (not p) s
//let returnCont = fun n -> Cont(fun k -> k n)
let returnCont :'a->Cont<'b, 'a> = return'
//限定継続(http://www.haskell.org/haskellwiki/MonadCont_done_right)
let reset e = returnCont <| runCont e id
let shift e = Cont <| fun k -> runCont (e (returnCont << k)) id
[<EntryPoint>]
let main argv =
reset <| do'{
let! first = shift <| fun k -> do'{
let! second = k(1)
printfn "%A" (second, "2")
return 3
}
printfn "%A" (first, "1")
return 2
}
|> runCont <|
fun third -> printfn "%A" (third, "3")
0
#かっこいい
いろいろ遊べそう