On 2010 Oct 14, at 09:19, Evan Laforge wrote:

How
are you expecting to call the functions in that container? "for f in
c: try: return f(*misc_args) except: pass"?

to_do = [(call, (AuntMabel,)),
        (buy,  ([(12*kg, sugar), (6*bushel, wheat)])),
        (introduce, (Romeo, Juliet))]

for do,it in to_do:
   do(*it)

As has been pointed out, simply write it like this:

to_do = [call AuntMabel, buy [(12kg, sugar), (6 bushel, weat)], etc.]

Which works for this case, but not in general. For example here's the memoizer example I used in response to Brandon:

def memoize(fn):
   cache = {}
   def memoized_fn(*args):
       if args not in cache:
           cache[args] = fn(*args)
       return cache[args]
   return memoized_fn

You memoize a function once, but it will be given different arguments, many times, at a later time.

But what should the type of fn be? What should the type of args be? In Python, I don't care, as long no type error occurs when they are combined thus:

   fn(*args)

How do you let Haskell type check the combination of the types, rather than the individual types?

My answer seems to be: define a variant type for holding the combinations. The problem with this is that the set of allowed combinations is closed at library compile time. I want it to remain open for extension. In Duck Typing this happens trivially.

If they are monadic actions, you can call 'sequence_' on them when you
want them to "happen".  If not, you really just have a list.

The thing is, I can arrange for them to be compatible. Python won't be able to confirm this statically, but is it too much to ask of Haskell to have it
figure out (statically) that all of

   (Int -> Bool, Int)
(Banana -> Apple -> Orange -> Kiwi -> Bool, (Banana, Apple, Orange,
Kiwi))
   (Bool -> Bool -> Bool, (Bool, Bool))

can be combined to give Bool ?

Yes, this sounds like an existential:

data Boolable forall a. = Boolable (a -> Bool)

But despite the fact that I've been keeping them in the back of my
mind for years, I've never once come up with a place where one would
actually be useful.  I guess I just don't think that way.

I think that Haskell allows so many completely different approaches to things, that serious Haskell programmers are essentially using completely different languages which share a small common core :-)

I agree with you
that this is sometimes easier in a dynamic language because you can
reuse the implementation language at runtime.

I don't think I'm looking for that in this case. I'm just asking to be
allowed to stick both

   (A -> B -> X, (A, B))

and

   (C -> D -> E -> X, (C, D, E))

etc. in the same container, because, frankly, in the context in which they
are used, they *are* the same.

Maybe you should focus less on the particular implementation you want
and more on the end result?  If you start off saying "I want
heterogenous lists" then you'll start off with a problem for haskell
:)

Of course. Please don't get the impression that I'm trying to fit things into my box and won't accept anything else. I'm here to learn. In the process of explaining what I mean in some particular case, I end up using language from which says that "I want this", but that only refers to the exploration of one particular approach.

I am open to, and eagerly encourage, completely different suggestions.

Haskell doesn't have the interpreter around at runtime.  But if
you know exactly what parts of the interpreter you want, you can
recover them, i.e. with Dynamic or by using 'hint' in the extreme.

Hint. Hmm. Embedding an interpreter into your code. I can imagine lots of interesting uses for this. But I don't think I want/need it in this case.

Thanks for pointing it out, though.


apply1 f [x] = f x
apply1 _ _ = throw hissy fit
apply2 f [x, y] = f x y
etc.

I would hope that the types could be checked statically, as I explained
above.

They can.  The strings coming in from the user, of course they can't,

Sure, but that's why we have a ParseError constructor in our Question type.

because they're not even known statically.  The 'apply1' function, of
course, is statically checked in that 'f' is required to be a function
with a single string argument.  Well, of the same type as the list
passed.

But I feel rather cramped by x and y in apply2 being constrained to having the same type.


I'm pretty sure that you could never come up with a sufficiently large set of primitives. Even if you could, it seems like far too much work, given that the ability to store arbitrary (sets of co-operating) functions (which, together, always return the same types) in the same container, trivially
provides you with full generality.

Could you provide a more concrete example?  So far the simple example
of int accepting functions with different arities is pretty easy to
implement with a plain list,

Trivial, as long as you combine the components immediately. If you need to hold the components separately it becomes trickier. Specifically, you need to create a variadic wrapper for holding the components, at which point you lose extensibility.

Again, I'm sure this isn't the only way, but it's the one that my inexperienced mind sees immediately.

so maybe you could provide a bit of
python or something that does what you want and would be harder with
static types?

Is the memoizer show above sufficient? If not I'll try to distil a minimal set of conflicting question types in the maths test example.

Eventually, some invisible line is crossed and you have
an EDSL for writing math tests.

That is *exactly* where I am heading with this.

Well, good, haskell's supposed to be good at EDSLs :)

Your Question type could look like
'String -> Answer' and Answer = 'Wrong String | Right | ParseError
String'.

Actually, I think it should be more like:

Answer = ParseError String | Wrong String | NeitherWrongNorRightSoTryAgain
String | Right

Well sure, the point is that neither of these types are even
polymorphic, let alone existential.

Yes, it's completely irrelevant to the meat of the discussion.

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to