[Haskell-beginners] OpenGL keyboardMouseCallback ...confused over type

Daniel Fischer daniel.is.fischer at googlemail.com
Fri Jul 1 10:55:34 CEST 2011


Just to elaborate a bit:

On Friday 01 July 2011, 10:19:04, Sean Charles wrote:
> On 30/06/11 23:53, Arlen Cuss wrote:
> [snip]
> 
> >> and modify the assignment in main to this:
> >>      keyboardMouseCallback $= Just (myKeyMouse gameState)
> 
> I think that part of my confusion was, on reflection, caused by the fact
> that coming from a procedural background, the syntax of "Just
> (myKeyMouse gameState) still reads as "function call arguments", so if I
> may be permitted to expand on that to see if I now understand Haskell a
> little more ...
> 
> The form: "Just (myKeyMouse gameState)" looks like its calling the Just
> function with two parameters as the () is also used to define a tuple.

No, the tuple constructors have commas, "(a,b)" is a tuple, "(a b)" is a 
grouping, meaning "the function a applied to the argument b". Putting such 
in parentheses may be necessary if e.g., like here, that expression is the 
argument of another function.

Just (myKeyMouse gameState) === Just $ myKeyMouse gameState

is "the function [value constructor] Just, applied to the result of 
applying myKeyMouse to gameState".

> So is (myKeyMouse gameState) a tuple of one, the result of calling that
> function with that parameter or is just a way of ensuring that the
> function is performed before it is passed to Just as the one and only
> parameter?

Yes, except Haskell doesn't have a concept of one-tuples, they're just 
plain values.

> 
> I know the correct  answer but I did sometimes get confused over when is
> a tuple "()" not a tuple, especially in things like this:

Parentheses are

a) a value [or type] constructor, when there's nothing in between: ()
b) grouping signifiers, like in (3+4)*5 or in

foo (x:xs) = ...

where they delimit the pattern to match; without the parentheses, it would 
be parsed as

(foo x) : xs = ...

which would be a definition of (:), except it would be a syntax error
[foo x is not a valid patter] and (:) is an infix-constructor, which can't 
be defined by a function binding]

c) a means to make prefix functions from infix operators, like (++)

Visually similar to parentheses, but different are tuple constructors:

(,) :: a -> b -> (a,b)
(,,) :: a -> b -> c -> (a,b,c)
...

the parentheses are part of the constructors, these constructors can be 
applied prefix or roundfix (special wired in syntax, as for lists,
"[] a" is the same type as "[a]", but for tuples, it works for values too).

> 
> foo (x:xs) = ...
> 
> I *know* it is pattern matching using ':' and that ':' takes a thing and
> a list of things and returns a list of same things but old habits.. DOH!
> 
> Back to the chase.
> 
> If I had rewritten the Just called like this I think it would have been
> clearer about what was happening:
> 
>    Just $ myKeyMouse gameState
> 
> as that quite clearly says, call myKeyMouseFirst and then hand the
> result to Just. From that point, Arlens great description of how it
> trundles through the type system, resulting in a partially evaluated
> function that has the *same* type as the expected one for the
> keyboardMouseCallback is really making it clearer for me now. That was a
> loud Eureka moment in my kitchen over breakfast this morning I can tell
> you!
> 
> It just needs to settle in and join the rest of the facts jostling for
> top position on the "Don't forget..." list.
> 
> Once again "list", I thank thee muchly for helping this troubador of
> trouble travel the road to Haskell...
> 
> :)




More information about the Beginners mailing list