1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

限定継続でAmb

Posted at

#amb
ambは非決定性計算をしてくれるカッコイイオペレータである。
Rosetta CodeにあるAmbの例題前回の限定継続を利用して解いてみる。

#コード
NotUseAmbをdefineすると今回用意したambの代わりにリストモナドを使う。


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()


#if NotUseAmb
#else

let runCont = Cont.run

#endif

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 :'a->Cont<'b, 'a> = return'

#if NotUseAmb

let amb (lst:List<_>) = lst
let require condition = if condition then [()] else []
let reset k = k
let runCont a b = b(a)

#else

let reset e = returnCont <| runCont e id
let shift e = Cont <| fun k -> e (returnCont << k) |> runCont <| id

let amb lst = shift <| fun k -> do'{
    lst
    |> List.iter (fun x -> ignore <| do'{
        do! (k x)
    })
    return ()
}
let require condition = shift <| fun k -> do'{
    if condition then
        do! k ()
        return ()
    else
        return ()
}

#endif

[<EntryPoint>]
let main argv = 

    let isFollowedBy (a: string) (b: string) =
        a.[a.Length - 1] = b.[0]

    reset <| do'{
        let! first = amb ["the"; "that"; "a"]
        //printfn "a1"
        let! second = amb ["frog"; "elephant"; "thing"]
        //printfn "a2"
        do! require(first |> isFollowedBy <| second)
        //printfn "r1"
        let! third = amb ["walked"; "treaded"; "grows"]
        //printfn "a3"
        do! require(second |> isFollowedBy <| third)
        //printfn "r2"
        let! forth = amb ["slowly"; "quickly"]
        //printfn "a4"
        do! require(third |> isFollowedBy <| forth)
        //printfn "r3"
        printfn "%A" (first, second, third, forth)
        return ()
    }
    |> runCont <|
        fun _ -> printfn "end"

    0

#つか
F#って#define書けないのな^^;

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?