Re: [Haskell-cafe] Currying function using values from array

2008-08-08 Thread Sukit Tretriluxana
Thanks so much for the response so far. To Lemming's question, this is just
a theoretical question. I try comparing what I can do in Groovy with
Haskell. So far I could come up with solutions but not this one. I'm not an
expert on this but I'm not sure if template haskell or type class would come
to rescue this situation. And if so, I wonder how it looks like.

Ed

On Fri, Aug 8, 2008 at 2:39 PM, Lemming <[EMAIL PROTECTED]>wrote:

> Sukit Tretriluxana schrieb:
>
>> Thanks Tom and Henning for your response. Let me put the question in
>> another way by generalizing and tweaking it a little bit.
>>
>> How in Haskell that I can create a function that curries *any *other
>> function, which receives multiple parameters, by using a the input from a
>> list (same data type) or a tuple (mixed data type) such that it either
>> returns another closure (if not all parameters are curried) or the final
>> value of the computation (when all parameters are known)?
>>
>
> Is this a theoretical question or do you actually need this? If yes, I
> wonder what application it may be.
>
>
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Currying function using values from array

2008-08-08 Thread Lemming

Sukit Tretriluxana schrieb:
Thanks Tom and Henning for your response. Let me put the question in 
another way by generalizing and tweaking it a little bit.


How in Haskell that I can create a function that curries *any *other 
function, which receives multiple parameters, by using a the input from 
a list (same data type) or a tuple (mixed data type) such that it either 
returns another closure (if not all parameters are curried) or the final 
value of the computation (when all parameters are known)?


Is this a theoretical question or do you actually need this? If yes, I 
wonder what application it may be.


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


Re: [Haskell-cafe] Currying function using values from array

2008-08-08 Thread Ryan Ingram
2008/8/7 Sukit Tretriluxana <[EMAIL PROTECTED]>:
> How in Haskell that I can create a function that curries any other function,
> which receives multiple parameters, by using a the input from a list (same
> data type) or a tuple (mixed data type) such that it either returns another
> closure (if not all parameters are curried) or the final value of the
> computation (when all parameters are known)?

Here's a solution that uses tuples only (no lists, they are somewhat
more difficult to typecheck correctly), along with several tests.

The payoff is functions with signatures like this:

-- tncurry :: (a -> b -> c -> r) -> (a,b,c) -> r
-- trcurry :: ((a,b,c) -> r) -> a -> b -> c -> r

-- ncurry :: (a -> b -> c -> r) -> (a, (b, (c, ( -> r
-- rcurry :: ((a, (b, (c, ( -> r) -> a -> b -> c -> r

but that work on any number of arguments.
(disclaimer: I've only implemented tncurry & trcurry up to 4-tuples;
additional tuple sizes require 3 lines of boilerplate code each).

   -- ryan

{-# OPTIONS_GHC -fglasgow-exts -fallow-undecidable-instances
-fno-monomorphism-restriction
  #-}
module Curry where

-- no-monomorphism-restriction is just so we don't
-- have to put dummy arguments on the tests.

class IsFunction f a r | f -> a r, a r -> f where
   apply :: f -> a -> r

instance IsFunction (a -> b) a b where
   apply = ($)

class NCurry f a r | f a -> r where
   ncurry :: f -> a -> r

instance NCurry r () r where
   ncurry x _ = x

instance (IsFunction f' b f, NCurry f a r) => NCurry f' (b,a) r where
   ncurry f (b,a) = ncurry (apply f b) a

class RCurry t x r | t x -> r where
   rcurry :: (t -> x) -> r

instance RCurry () r r where
   rcurry f = f ()

instance RCurry t x r => RCurry (a,t) x (a -> r) where
   rcurry f x = rcurry (\t -> f (x,t))

-- some tests

test1 = ncurry (+) (5, (10, ()))
-- test1 :: Num f => f
-- test1 => 15

plus :: Num a => (a, (a, ())) -> a
plus = ncurry (+)

test2 = rcurry plus
-- test2 :: Num a => a -> a -> a

test_broken = rcurry (ncurry (+))
-- test_broken :: (Num a, NCurry (a -> a -> a) t r, RCurry t r r1) => r1
{-
test_broken 5 10 =>
No instances for (NCurry (a -> a -> a) t r,
  RCurry t r (t1 -> t2 -> t3))

This is an instance of the "read.show" problem; ncurry (+) has many types:
ncurry (+) :: Num a => () -> a -> a -> a
ncurry (+) :: Num a => (a,()) -> a -> a
ncurry (+) :: Num a => (a,(a,())) -> a

Even though rcurry would work on any of these, it's ambiguous which one
to choose, so the type inferencer gives up.
-}

test3 = test2 5 10
-- test3 :: Num t => t
-- test3 => 15

-- stupid constant function
dumb a b c d = c

test4 = ncurry dumb ("wrong", (5, ("correct", ([1..50], ()
-- test4 :: [Char]
-- test4 => "correct"

dumb2 (a, (b, (c, (d, () = c

test5 = rcurry dumb2
-- test5 :: t -> t1 -> r -> t2 -> r

test6 = rcurry dumb2 "wrong" 5 "correct" [1..50]
-- test6 :: [Char]
-- test6 => "correct"

-- We can also use "real" tuples instead of tuple-lists, with
-- some boilerplate...

class TupleChange n t | n -> t, t -> n where
   toTuple :: n -> t
   fromTuple :: t -> n

-- Haskell doesn't have a "1-tuple", so make it ourselves
data Tuple1 x = Tuple1 x deriving (Eq, Show, Ord)

instance TupleChange () () where
   toTuple = id
   fromTuple = id

instance TupleChange (a, ()) (Tuple1 a) where
   toTuple (a, ()) = Tuple1 a
   fromTuple (Tuple1 a) = (a, ())

instance TupleChange (a, (b, ())) (a, b) where
   toTuple (a, (b, ())) = (a,b)
   fromTuple (a,b) = (a, (b, ()))

instance TupleChange (a, (b, (c, ( (a,b,c) where
   toTuple (a, (b, (c, ( = (a,b,c)
   fromTuple (a,b,c) = (a, (b, (c, (

instance TupleChange (a, (b, (c, (d, () (a,b,c,d) where
   toTuple (a, (b, (c, (d, () = (a,b,c,d)
   fromTuple (a,b,c,d) = (a, (b, (c, (d, ()

tncurry f = ncurry f . fromTuple
trcurry f = rcurry (f . toTuple)

-- Tests of tncurry/trcurry & show closures

test7 = tncurry (+) (Tuple1 5)
-- test7 :: Num a => a -> a
-- test7 10 => 15

dumb3 (a,b,c,d) = c

test8 = trcurry dumb3
-- test8 :: t -> t1 -> r -> t2 -> r

-- test9 creates a closure waiting for more
-- arguments...
test9 = tncurry dumb ("foo", "bar", "hat")
-- test9 :: t -> [Char]
-- test9 "baz" => "hat"

-- although you do have to use tncurry again
-- with each call if you want to keep applying
-- it with tuples
test10 = tncurry (tncurry dumb ("foo", "bar", "hat")) (Tuple1 "baz")
-- test10 :: [Char]
-- test10 => "hat"
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Currying function using values from array

2008-08-07 Thread Sukit Tretriluxana
Thanks Tom and Henning for your response. Let me put the question in another
way by generalizing and tweaking it a little bit.

How in Haskell that I can create a function that curries *any *other
function, which receives multiple parameters, by using a the input from a
list (same data type) or a tuple (mixed data type) such that it either
returns another closure (if not all parameters are curried) or the final
value of the computation (when all parameters are known)?

Ed

On Thu, Aug 7, 2008 at 12:49 PM, Tom Nielsen <[EMAIL PROTECTED]> wrote:

> Maybe you want something like
>
> curryWithList :: ([a]->b)->[a]->([a]->b)
> curryWithList f lst1= \lst2 ->f (lst1++lst2)
>
> addThemUp = sum
> curried = curryWithList addThemUp [1,2,3,4]
> curried [5] =15
>
> On Thu, Aug 7, 2008 at 8:35 PM, Henning Thielemann
> <[EMAIL PROTECTED]> wrote:
> >
> > On Thu, 7 Aug 2008, Sukit Tretriluxana wrote:
> >
> >> Dear Haskell experts,
> >>
> >> I am currently studying Groovy language. An experiment I did with its
> >> closure is to perform closure/function "curry" using an array containing
> the
> >> values for the parameter binding. See the sample below.
> >>
> >> int addThemUp(a,b,c,d,e) { a+b+c+d+e }
> >> def arrayCurry(arr, cls) { arr.inject(cls) { c, v -> c.curry(v) } }
> >> println addThemUp(1,2,3,4,5)
> >> println arrayCurry([1,2,3,4,5], this.&addThemUp)()
> >> println arrayCurry([1,2,3,4], this.&addThemUp)(5)
> >>
> >> The printouts from the above code are the same, verifying that the code
> >> works fine. Then I come to ask myself how I can do the same in Haskell.
> I'm
> >> not a Haskell expert so I couldn't figure it. I wonder if you guys could
> >> shed some light on this.
> >
> > I do not know Groovy, but maybe you want something like
> >
> >  addThemUp :: Num a => (a,a,a,a,a) -> a
> >  addThemUp (a,b,c,d,e) = a+b+c+d+e
> >
> >  -- should be better named list5Curry or so
> >  arrayCurry :: ((a,a,a,a,a) -> a) -> [a] -> a
> >  arrayCurry cls [a,b,c,d,e] = cls (a,b,c,d,e)
> >
> >  print (addThemUp(1,2,3,4,5::Int))
> >  print (arrayCurry addThemUp [1,2,3,4,5::Int])
> >
> > However, it's hardly of any use, since you won't use a list if the number
> > of elements is fixed (and small) or if the elements even must have
> > distinct types.
> > ___
> > Haskell-Cafe mailing list
> > Haskell-Cafe@haskell.org
> > http://www.haskell.org/mailman/listinfo/haskell-cafe
> >
>
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Currying function using values from array

2008-08-07 Thread Tom Nielsen
Maybe you want something like

curryWithList :: ([a]->b)->[a]->([a]->b)
curryWithList f lst1= \lst2 ->f (lst1++lst2)

addThemUp = sum
curried = curryWithList addThemUp [1,2,3,4]
curried [5] =15

On Thu, Aug 7, 2008 at 8:35 PM, Henning Thielemann
<[EMAIL PROTECTED]> wrote:
>
> On Thu, 7 Aug 2008, Sukit Tretriluxana wrote:
>
>> Dear Haskell experts,
>>
>> I am currently studying Groovy language. An experiment I did with its
>> closure is to perform closure/function "curry" using an array containing the
>> values for the parameter binding. See the sample below.
>>
>> int addThemUp(a,b,c,d,e) { a+b+c+d+e }
>> def arrayCurry(arr, cls) { arr.inject(cls) { c, v -> c.curry(v) } }
>> println addThemUp(1,2,3,4,5)
>> println arrayCurry([1,2,3,4,5], this.&addThemUp)()
>> println arrayCurry([1,2,3,4], this.&addThemUp)(5)
>>
>> The printouts from the above code are the same, verifying that the code
>> works fine. Then I come to ask myself how I can do the same in Haskell. I'm
>> not a Haskell expert so I couldn't figure it. I wonder if you guys could
>> shed some light on this.
>
> I do not know Groovy, but maybe you want something like
>
>  addThemUp :: Num a => (a,a,a,a,a) -> a
>  addThemUp (a,b,c,d,e) = a+b+c+d+e
>
>  -- should be better named list5Curry or so
>  arrayCurry :: ((a,a,a,a,a) -> a) -> [a] -> a
>  arrayCurry cls [a,b,c,d,e] = cls (a,b,c,d,e)
>
>  print (addThemUp(1,2,3,4,5::Int))
>  print (arrayCurry addThemUp [1,2,3,4,5::Int])
>
> However, it's hardly of any use, since you won't use a list if the number
> of elements is fixed (and small) or if the elements even must have
> distinct types.
> ___
> Haskell-Cafe mailing list
> Haskell-Cafe@haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Currying function using values from array

2008-08-07 Thread Henning Thielemann

On Thu, 7 Aug 2008, Sukit Tretriluxana wrote:

> Dear Haskell experts,
>
> I am currently studying Groovy language. An experiment I did with its
> closure is to perform closure/function "curry" using an array containing the
> values for the parameter binding. See the sample below.
>
> int addThemUp(a,b,c,d,e) { a+b+c+d+e }
> def arrayCurry(arr, cls) { arr.inject(cls) { c, v -> c.curry(v) } }
> println addThemUp(1,2,3,4,5)
> println arrayCurry([1,2,3,4,5], this.&addThemUp)()
> println arrayCurry([1,2,3,4], this.&addThemUp)(5)
>
> The printouts from the above code are the same, verifying that the code
> works fine. Then I come to ask myself how I can do the same in Haskell. I'm
> not a Haskell expert so I couldn't figure it. I wonder if you guys could
> shed some light on this.

I do not know Groovy, but maybe you want something like

  addThemUp :: Num a => (a,a,a,a,a) -> a
  addThemUp (a,b,c,d,e) = a+b+c+d+e

  -- should be better named list5Curry or so
  arrayCurry :: ((a,a,a,a,a) -> a) -> [a] -> a
  arrayCurry cls [a,b,c,d,e] = cls (a,b,c,d,e)

  print (addThemUp(1,2,3,4,5::Int))
  print (arrayCurry addThemUp [1,2,3,4,5::Int])

However, it's hardly of any use, since you won't use a list if the number
of elements is fixed (and small) or if the elements even must have
distinct types.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe