My Continuation doesn't typecheck

Hello all, in order to gain some intuition about continuations, I tried the following: -- two functions accepting a continuation f1 :: Int -> (Integer->r) -> r f1 a c = c $ fromIntegral (a+1) f2 :: Integer -> (String -> r) -> r f2 b c = c $ show b -- combine the two functions into a single one run1 :: Int -> (String -> r) -> r run1 a = f1 a f2 -- *Main> run1 9 id -- "10" So far so good. Then I tried to write a general combinator, which does not have f1 and f2 hardcoded: combine a f g = f a g -- This also works -- *Main> combine 9 f1 f2 id -- "10" What confuses me is the the type of combine. I thought it should be combine :: Int -> (Int -> (Integer->r) -> r) -> -- f1 (Integer -> (String -> r) -> r) -> -- f2 ((String -> r) -> r) but that doesn't typecheck: Couldn't match expected type ‘(String -> r) -> r’ with actual type ‘r’ Can you tell me where I am making a mistake?

The only way to do this is to do it step by step. :t combine combine :: t1 -> (t1 -> t2 -> t) -> t2 -> t
:t combine 9 combine 9 :: Num t1 => (t1 -> t2 -> t) -> t2 -> t
:t f1 f1 :: Int -> (Integer -> r) -> r :t combine 9 f1 combine 9 f1 :: (Integer -> t) -> t
:t f2 f2 :: Integer -> (String -> r) -> r :t combine 9 f1 f2 combine 9 f1 f2 :: (String -> r) -> r
At some point the t2 in combine becomes a function, which causes the rest
of the type to change. I feel like combine was meant to be something else,
f (g a) or g (f a) or something else, but I'm not sure what.
On Sat, Aug 6, 2016 at 4:03 AM, martin
Hello all,
in order to gain some intuition about continuations, I tried the following:
-- two functions accepting a continuation
f1 :: Int -> (Integer->r) -> r f1 a c = c $ fromIntegral (a+1)
f2 :: Integer -> (String -> r) -> r f2 b c = c $ show b
-- combine the two functions into a single one
run1 :: Int -> (String -> r) -> r run1 a = f1 a f2
-- *Main> run1 9 id -- "10"
So far so good.
Then I tried to write a general combinator, which does not have f1 and f2 hardcoded:
combine a f g = f a g
-- This also works
-- *Main> combine 9 f1 f2 id -- "10"
What confuses me is the the type of combine. I thought it should be
combine :: Int -> (Int -> (Integer->r) -> r) -> -- f1 (Integer -> (String -> r) -> r) -> -- f2 ((String -> r) -> r)
but that doesn't typecheck:
Couldn't match expected type ‘(String -> r) -> r’ with actual type ‘r’
Can you tell me where I am making a mistake?
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

David, I used your method of hardcoding some of the parameters to find the correct type of 'combine'. It is not at all what I expected or wanted, but here it is: combine :: Int -> (Int -> (Integer -> (String -> r) -> r) -> (String -> r) -> r -> String) -> (Integer -> (String -> r) -> r) -> (String -> r) -> r -> String Not sure what this is trying to tell me. Am 08/06/2016 um 07:01 PM schrieb David McBride:
The only way to do this is to do it step by step. :t combine combine :: t1 -> (t1 -> t2 -> t) -> t2 -> t
:t combine 9 combine 9 :: Num t1 => (t1 -> t2 -> t) -> t2 -> t
:t f1 f1 :: Int -> (Integer -> r) -> r :t combine 9 f1 combine 9 f1 :: (Integer -> t) -> t
:t f2 f2 :: Integer -> (String -> r) -> r :t combine 9 f1 f2 combine 9 f1 f2 :: (String -> r) -> r
At some point the t2 in combine becomes a function, which causes the rest of the type to change. I feel like combine was meant to be something else, f (g a) or g (f a) or something else, but I'm not sure what.
On Sat, Aug 6, 2016 at 4:03 AM, martin
mailto:martin.drautzburg@web.de> wrote: Hello all,
in order to gain some intuition about continuations, I tried the following:
-- two functions accepting a continuation
f1 :: Int -> (Integer->r) -> r f1 a c = c $ fromIntegral (a+1)
f2 :: Integer -> (String -> r) -> r f2 b c = c $ show b
-- combine the two functions into a single one
run1 :: Int -> (String -> r) -> r run1 a = f1 a f2
-- *Main> run1 9 id -- "10"
So far so good.
Then I tried to write a general combinator, which does not have f1 and f2 hardcoded:
combine a f g = f a g
-- This also works
-- *Main> combine 9 f1 f2 id -- "10"
What confuses me is the the type of combine. I thought it should be
combine :: Int -> (Int -> (Integer->r) -> r) -> -- f1 (Integer -> (String -> r) -> r) -> -- f2 ((String -> r) -> r)
but that doesn't typecheck:
Couldn't match expected type ‘(String -> r) -> r’ with actual type ‘r’
Can you tell me where I am making a mistake?
_______________________________________________ Beginners mailing list Beginners@haskell.org mailto:Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

Have you heard of Djinn?
https://hackage.haskell.org/package/djinn
If you punch in the signature of the combine function you're looking for
(rewritten more usefully in Kleisli composition form):
(Int -> (Integer->r) -> r) ->
(Integer -> (String -> r) -> r) ->
(Int -> (String -> r) -> r)
you'll get your wish granted. Djinn will magically write combine for you.
It'll work even if you abstract over the concrete types of Int, Integer,
String.
You can popover to the haskell IRC to try it out on the djinn bot there if
installation is too much of a bother.
Best, Kim-Ee
On Saturday, August 6, 2016, martin
Hello all,
in order to gain some intuition about continuations, I tried the following:
-- two functions accepting a continuation
f1 :: Int -> (Integer->r) -> r f1 a c = c $ fromIntegral (a+1)
f2 :: Integer -> (String -> r) -> r f2 b c = c $ show b
-- combine the two functions into a single one
run1 :: Int -> (String -> r) -> r run1 a = f1 a f2
-- *Main> run1 9 id -- "10"
So far so good.
Then I tried to write a general combinator, which does not have f1 and f2 hardcoded:
combine a f g = f a g
-- This also works
-- *Main> combine 9 f1 f2 id -- "10"
What confuses me is the the type of combine. I thought it should be
combine :: Int -> (Int -> (Integer->r) -> r) -> -- f1 (Integer -> (String -> r) -> r) -> -- f2 ((String -> r) -> r)
but that doesn't typecheck:
Couldn't match expected type ‘(String -> r) -> r’ with actual type ‘r’
Can you tell me where I am making a mistake?
_______________________________________________ Beginners mailing list Beginners@haskell.org javascript:; http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
-- -- Kim-Ee

Am 08/07/2016 um 05:18 PM schrieb Kim-Ee Yeoh:
Have you heard of Djinn?
https://hackage.haskell.org/package/djinn
If you punch in the signature of the combine function you're looking for (rewritten more usefully in Kleisli composition form):
(Int -> (Integer->r) -> r) -> (Integer -> (String -> r) -> r) -> (Int -> (String -> r) -> r)
Thanks for pointing out Djinn, but I want to understand. And there are a number of things I don't understand. Maybe you can help me out: (1) what is the "more useful Kleisli composition" and what would be "less useful" ? (2) I was hoping my experiments would eventually make the Cont monad appear and I originally even named my combinator 'bind' instead of 'combine'. My hope was fueled by the observation that combine a f g = f a g works with f substitued with f1 :: Int -> (Integer->r) -> r and g substitued with f2 :: Integer -> (String -> r) -> r As a next step I would have wrapped (b->r) -> r in a newtype C r b and my functions f1 and f2 would have had the types f1 :: Int -> C r Integer f2 :: Integer -> C r String Now my 'combine' function seems to be different from 'bind' (>>=). It also just too simple to be true. Somwhere I am making a fundamental mistake, but I cannot quite see it.

(1) what is the "more useful Kleisli composition" and what would be "less useful" ?
This type signature (Int -> (Integer->r) -> r) -> (Integer -> (String -> r) -> r) -> (Int -> (String -> r) -> r) is the Cont monad instantiation of (>=>) :: Monad http://hackage.haskell.org/package/base-4.9.0.0/docs/Control-Monad.html#t:Mo... m => (a -> m b) -> (b -> m c) -> a -> m c See http://hackage.haskell.org/package/base-4.9.0.0/docs/ Control-Monad.html#v:-62--61--62- Being more uniform, this signature is more useful than the one you had earlier worked with: combine :: Int -> (Int -> (Integer->r) -> r) -> -- f1 (Integer -> (String -> r) -> r) -> -- f2 ((String -> r) -> r)
Now my 'combine' function seems to be different from 'bind' (>>=). It also just too simple to be true.
You got Kleisli composition, although not monadic bind. That's still a win
of sorts.
Best, Kim-Ee Yeoh
On Monday, August 8, 2016, martin
Am 08/07/2016 um 05:18 PM schrieb Kim-Ee Yeoh:
Have you heard of Djinn?
https://hackage.haskell.org/package/djinn
If you punch in the signature of the combine function you're looking for (rewritten more usefully in Kleisli composition form):
(Int -> (Integer->r) -> r) -> (Integer -> (String -> r) -> r) -> (Int -> (String -> r) -> r)
Thanks for pointing out Djinn, but I want to understand. And there are a number of things I don't understand. Maybe you can help me out:
(1) what is the "more useful Kleisli composition" and what would be "less useful" ?
(2) I was hoping my experiments would eventually make the Cont monad appear and I originally even named my combinator 'bind' instead of 'combine'. My hope was fueled by the observation that
combine a f g = f a g
works with f substitued with f1 :: Int -> (Integer->r) -> r and g substitued with f2 :: Integer -> (String -> r) -> r
As a next step I would have wrapped (b->r) -> r in a newtype C r b and my functions f1 and f2 would have had the types
f1 :: Int -> C r Integer f2 :: Integer -> C r String
Now my 'combine' function seems to be different from 'bind' (>>=). It also just too simple to be true.
Somwhere I am making a fundamental mistake, but I cannot quite see it.
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
-- -- Kim-Ee
participants (3)
-
David McBride
-
Kim-Ee Yeoh
-
martin