On 22 Apr 2008, at 9:53 AM, Ryan Ingram wrote:
On Mon, Apr 21, 2008 at 10:58 PM, Jonathan Cast
<[EMAIL PROTECTED]> wrote:
I must have failed to communicate well. To me, the point of
giving a class
a name is that then you can write a program that is parametric
over the
elements of that class. Knowing that I can implement monads in
Ruby doesn't
impress me nearly as much as knowing that I can implement mapM does.
Haskell has me addicted to code reuse (mapM) the way the rest of the
programming world is addicted to design patterns (monads). What I
mean by
`encoding Num and Monad' is that you can do something like this:
sum = foldr (+) 0
sequence = foldr (liftM2 (:)) (return [])
I don't know of any language that is dynamically typed and also
can encode
`return' or `0' in a way that lets those examples work.
Statically typed
languages where it works are rare, even. Haskell gives up a fair
amount of
control by making these things implicit, which is what I think you're
running up against --- but I think it gets something useful and
non-trivial
to acheive in return.
I think ruby generally solves this problem via duck-typing; instead of
the cast happening in the (implicit) fromInteger call in sum above,
instead the cast happens in the function with more information via a
call to otherclass#to_whatever_i_am. You can do something like this:
class Frob
attr_reader :val
def initialize(i)
@val = i
end
def to_frob
self
end
def +(rhs)
rhsF = rhs.to_frob
Frob.new(rhsF.val + @val)
end
end
class Integer
def to_frob
Frob.new(self)
end
end
class Array
def sum
foldl(0) {|acc,x| acc + x}
end
def foldl(z)
each {|x| z = yield(z,x)}
z
end
end
irb(main):055:0> [1,2,3].sum
=> 6
irb(main):057:0> [1,2,3].map {|x| Frob.new(x)}.sum
=> #<Frob:0x2b65cf0 @val=6>
How do I extend Num, in this case? Assign into the Integer namespace
(maybe the wrong terminology, I don't know Ruby and don't want to)?
I've considered designs like this, but they feel like a hack compared
to type classes.
I'll agree with this point. I've complained, concretely, about
the lack of
instances for (some) standard types before. (STM is actually a
rather bad
offender here; it's lacking MonadPlus, as well, despite the specific
observation in the paper that it has the right signature for that
class.)
Actually:
GHCi, version 6.8.2: http://www.haskell.org/ghc/ :? for help
Loading package base ... linking ... done.
Prelude> :m Control.Monad Control.Monad.STM
Prelude Control.Monad.STM Control.Monad> :i STM
...
instance MonadPlus STM -- Defined in Control.Monad.STM
OK. I was going off the documentation (which is spotty for STM anyway).
When can we discharge a MaybeInstance context?
On any concrete type. Like Typeable should be :)
The compiler then determines whether that type is an instance of the
class and provides the appropriate dictionary if applicable.
This works if orphan instances are outlawed. That invalidates
Haskell 98 programs, of course, including ones both of us have
written. Forbidding those would be an interesting language design
choice, of course, and would make most of what you've asked for
sensible. Hmm.
Having the | Show a test suddenly trip from False to True because
some
other module imported Text.Show.Functions sounds like an odd
change to me.
At any rate, it scares me enough to make me oppose the idea.
I see the worry now. I think this is more of a problem with orphan
instances; are orphan instances considered to be a valuable enough
feature to avoid potentially more powerful constructs?
Maybe there is a better solution to the "I have class C from library X
and type T from library Y and I want to make them play nice together"
problem than orphan instances.
I can't think of one, for the general case, but I guarantee I'll be
worrying about both questions until I think I know the answer...
<snip>
jcc
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe