|
|
Invisible wrote:
> It does those things in the order given. If you assign a result to a
> variable, that result stays the same thereafter.
OK. Same as Erlang. :-)
> And you can do
>
> do
> foo
> let x = print "hello"
> bar
> x
>
> which will print "hello" immediately after performing "bar". Nothing
> hard here. ;-)
Same as Erlang, except you'd have to make it explicitly a fun (aka lambda).
> Consider the Maybe monad. It's useful for functions that might fail. For
> example,
>
> solve :: Double -> Double -> Maybe Double
> solve a b = if a == 0 then Nothing else Just ((0 - b)/a)
solve(A,B) when A == 0 -> nothing;
solve(A,B) -> ((0-B)/A).
(Note that "nothing" here is just an "atom", i.e., an interned string, a
LISP "symbol", a Smalltalk "symbol", etc. It's not a special value or
type. Just something you can match on later.)
> So you see that ">>=" takes a Maybe and a function that returns a Maybe,
> and... well, let me just write the code, it's faster:
>
> (Just x) >>= f = f x
> (Nothing) >>= f = Nothing
>
> So when you do "solve j k >>= f", if solve returns Nothing, just skip f
> completely and return Nothing directly. Otherwise, take whatever data
> came from solve, fish it out of the Maybe value, and feed it to f.
do_maybe(Fun, X) when X == nothing -> nothing;
do_maybe(Fun, X) -> Fun(X).
Probably not equivalent in a deeper sense.
But you're giving me some ideas for some higher-order functions I
probably need. I still miss "while" loops, but I've been trying to
figure out how to make while() into a function that takes two lambdas. :-)
> In other words, we can now have a chain of actions where a single
> failure triggers an escape from the whole sequence - but doesn't clutter
> up the logic of the program on paper.
Yep.
> Now we can do exactly the same thing with lists. If you think about it,
> a Maybe stores either 0 or 1 results. Well, a list can store 0 or 1 or 2
> or 3 or...
>
> xs >>= f = concat (map f xs)
>
> As should be clear, if xs is the empty list, f is never run at all, and
> you just get an empty list as the result. This is like the Maybe case.
> Assuming xs is a nonempty list, run f for every element in xs and merge
> the results.
>
> It gets slightly confusing when you start using do-notation, but it's
> quite powerful:
>
> factors k = do
> x <- [1..10]
> y <- [1..10]
> if x * y == k then [(x,y)] else []
In Erlang:
factors(K) ->
Seq = lists:seq(1,K),
[ X*Y || X <- Seq, Y <- Seq, X * Y == K ].
Thanks for the explanation. I'm still not 100% sure what the "value" in
the monad returned by getclock looks like, tho. I know it's supposed to
be opaque, but what in theory is in there, could you say?
> PS. If you've got a moment, there's a Tcl implementation of my logic
> solver over in the povray.off-topic.haskell. I'd be interested to know
> if you can make it any less... butt-ugly, for want of a better word!
Wow. You have your own newsgroup. :-)
I'll take a look.
--
Darren New / San Diego, CA, USA (PST)
"That's pretty. Where's that?"
"It's the Age of Channelwood."
"We should go there on vacation some time."
Post a reply to this message
|
|