X-Git-Url: https://gitweb.factorcode.org/gitweb.cgi?p=factor.git;a=blobdiff_plain;f=extra%2Fmonads%2Fmonads.factor;h=851e1ff0445cabb5e6eedee898750584ab3b5c4d;hp=bff720b2a36b506bcb5bc5d15f1bacbcb53cbf2e;hb=HEAD;hpb=44f53de16496395a16862da780792a0fecf10316 diff --git a/extra/monads/monads.factor b/extra/monads/monads.factor index bff720b2a3..b42d5c6fed 100644 --- a/extra/monads/monads.factor +++ b/extra/monads/monads.factor @@ -1,12 +1,12 @@ ! Copyright (C) 2008 Slava Pestov -! See http://factorcode.org/license.txt for BSD license. -USING: arrays kernel sequences sequences.deep splitting -accessors fry locals combinators namespaces lists lists.lazy -shuffle ; +! See https://factorcode.org/license.txt for BSD license. +USING: accessors arrays kernel lists lists.lazy sequences ; IN: monads ! Functors -GENERIC# fmap 1 ( functor quot -- functor' ) inline +GENERIC#: fmap 1 ( functor quot -- functor' ) +GENERIC#: <$ 1 ( functor quot -- functor' ) +GENERIC#: $> 1 ( functor quot -- functor' ) ! Monads @@ -21,8 +21,9 @@ GENERIC: >>= ( mvalue -- quot ) M: monad return monad-of return ; M: monad fail monad-of fail ; -: bind ( mvalue quot -- mvalue' ) swap >>= call ; -: >> ( mvalue k -- mvalue' ) '[ drop , ] bind ; +: bind ( mvalue quot -- mvalue' ) swap >>= call( quot -- mvalue ) ; +: bind* ( mvalue quot -- mvalue' ) '[ drop @ ] bind ; +: >> ( mvalue k -- mvalue' ) '[ drop _ ] bind ; :: lift-m2 ( m1 m2 f monad -- m3 ) m1 [| x1 | m2 [| x2 | x1 x2 f monad return ] bind ] bind ; @@ -30,14 +31,14 @@ M: monad fail monad-of fail ; :: apply ( mvalue mquot monad -- result ) mvalue [| value | mquot [| quot | - value quot call monad return + value quot call( value -- mvalue ) monad return ] bind ] bind ; -M: monad fmap over '[ @ , return ] bind ; +M: monad fmap over '[ @ _ return ] bind ; ! 'do' notation -: do ( quots -- result ) unclip dip [ bind ] each ; +: do ( quots -- result ) unclip [ call( -- mvalue ) ] curry dip [ bind ] each ; ! Identity SINGLETON: identity-monad @@ -51,7 +52,7 @@ M: identity monad-of drop identity-monad ; M: identity-monad return drop identity boa ; M: identity-monad fail "Fail" throw ; -M: identity >>= value>> '[ , swap call ] ; +M: identity >>= value>> '[ _ swap call( x -- y ) ] ; : run-identity ( identity -- value ) value>> ; @@ -62,18 +63,18 @@ INSTANCE: maybe-monad monad SINGLETON: nothing TUPLE: just value ; -: just ( value -- just ) \ just boa ; +C: just UNION: maybe just nothing ; INSTANCE: maybe monad M: maybe monad-of drop maybe-monad ; -M: maybe-monad return drop just ; +M: maybe-monad return drop ; M: maybe-monad fail 2drop nothing ; -M: nothing >>= '[ drop , ] ; -M: just >>= value>> '[ , swap call ] ; +M: nothing >>= '[ drop _ ] ; +M: just >>= value>> '[ _ swap call( x -- y ) ] ; : if-maybe ( maybe just-quot nothing-quot -- ) pick nothing? [ 2nip call ] [ drop [ value>> ] dip call ] if ; inline @@ -83,21 +84,21 @@ SINGLETON: either-monad INSTANCE: either-monad monad TUPLE: left value ; -: left ( value -- left ) \ left boa ; +C: left TUPLE: right value ; -: right ( value -- right ) \ right boa ; +C: right UNION: either left right ; INSTANCE: either monad M: either monad-of drop either-monad ; -M: either-monad return drop right ; -M: either-monad fail drop left ; +M: either-monad return drop ; +M: either-monad fail drop ; -M: left >>= '[ drop , ] ; -M: right >>= value>> '[ , swap call ] ; +M: left >>= '[ drop _ ] ; +M: right >>= value>> '[ _ swap call( x -- y ) ] ; : if-either ( value left-quot right-quot -- ) [ [ value>> ] [ left? ] bi ] 2dip if ; inline @@ -112,7 +113,7 @@ M: array-monad fail 2drop { } ; M: array monad-of drop array-monad ; -M: array >>= '[ , swap map concat ] ; +M: array >>= '[ _ swap map concat ] ; ! List SINGLETON: list-monad @@ -124,30 +125,30 @@ M: list-monad fail 2drop nil ; M: list monad-of drop list-monad ; -M: list >>= '[ , swap lazy-map lconcat ] ; +M: list >>= '[ _ swap lmap-lazy lconcat ] ; ! State SINGLETON: state-monad INSTANCE: state-monad monad TUPLE: state quot ; -: state ( quot -- state ) \ state boa ; +C: state INSTANCE: state monad M: state monad-of drop state-monad ; -M: state-monad return drop '[ , 2array ] state ; +M: state-monad return drop '[ _ 2array ] ; M: state-monad fail "Fail" throw ; -: mcall ( state -- ) quot>> call ; +: mcall ( x state -- y ) quot>> call( x -- y ) ; -M: state >>= '[ , swap '[ , mcall first2 @ mcall ] state ] ; +M: state >>= '[ _ swap '[ _ mcall first2 @ mcall ] ] ; -: get-st ( -- state ) [ dup 2array ] state ; -: put-st ( value -- state ) '[ drop , f 2array ] state ; +: get-st ( -- state ) [ dup 2array ] ; +: put-st ( value -- state ) '[ drop _ f 2array ] ; -: run-st ( state initial -- ) swap mcall second ; +: run-st ( state initial -- value ) swap mcall second ; : return-st ( value -- mvalue ) state-monad return ; @@ -156,37 +157,37 @@ SINGLETON: reader-monad INSTANCE: reader-monad monad TUPLE: reader quot ; -: reader ( quot -- reader ) \ reader boa ; +C: reader INSTANCE: reader monad M: reader monad-of drop reader-monad ; -M: reader-monad return drop '[ drop , ] reader ; +M: reader-monad return drop '[ drop _ ] ; M: reader-monad fail "Fail" throw ; -M: reader >>= '[ , swap '[ dup , mcall @ mcall ] reader ] ; +M: reader >>= '[ _ swap '[ dup _ mcall @ mcall ] ] ; -: run-reader ( reader env -- ) swap mcall ; +: run-reader ( reader env -- value ) swap quot>> call( env -- value ) ; -: ask ( -- reader ) [ ] reader ; -: local ( reader quot -- reader' ) swap '[ @ , mcall ] reader ; +: ask ( -- reader ) [ ] ; +: local ( reader quot -- reader' ) swap '[ @ _ mcall ] ; ! Writer SINGLETON: writer-monad INSTANCE: writer-monad monad TUPLE: writer value log ; -: writer ( value log -- writer ) \ writer boa ; +C: writer M: writer monad-of drop writer-monad ; -M: writer-monad return drop { } writer ; +M: writer-monad return drop { } ; M: writer-monad fail "Fail" throw ; : run-writer ( writer -- value log ) [ value>> ] [ log>> ] bi ; -M: writer >>= '[ [ , run-writer ] dip '[ @ run-writer ] dip append writer ] ; +M: writer >>= '[ [ _ run-writer ] dip '[ @ run-writer ] dip prepend ] ; -: pass ( writer -- writer' ) run-writer [ first2 ] dip swap call writer ; -: listen ( writer -- writer' ) run-writer [ 2array ] keep writer ; -: tell ( seq -- writer ) f swap writer ; +: pass ( writer -- writer' ) run-writer [ first2 ] dip swap call( x -- y ) ; +: listen ( writer -- writer' ) run-writer [ 2array ] keep ; +: tell ( seq -- writer ) f swap ;