I have to remind myself: Each time I use (if/then/else), check if I should rather use pattern matching or a guard. Also interesting to follow your thought process on handleEvent. I "cheated" and used Maybe and `orElse` to compose the different potentially event handling use cases (win, move player, move box, change direction, or else keep existing state if any other key was pressed).
On the names: If you have a concrete value like a specific tile, it should have a descriptive name, even in Haskell. But the more abstract a function is, e. g. like mapList, the less descriptive names can be and long names just become a distraction, e. g. `x xs` instead of `firstElement remainingElements`.
I've heard this argument and understand it, but I find that there comes a point where when a token is too short (and "x" and "xs" are good examples of this) my eyes just slide right over it, and this is much more distracting to me than if they had meaningless but recognizable names.
In Haskell all functions are implicitly curried. This means that the following to type signatures are the same: ``` moveFromTo :: Coord -> Coord -> Coord -> Coord moveFromTo :: Coord -> Coord -> (Coord -> Coord) ```
This is one of those things that I could explain on a whiteboard, but somehow when writing code never sticks in my brain, except when I'm doing cutesy "point free" code, and even then it's extra mental effort to get it right.
@@TeaLeavesProgramming A haskell function: ``` add x y = x + y ``` Is constructed internally like this: ``` add = \x -> \y -> x + y ``` or using javascript syntax cause its the universal language: ``` let add = (x) => (y) => x + y ``` Does that help?
So `add` can be seen as a function that takes two numbers and adds them together but realy its a function that takes a number and produces another function that takes a number and then adds the two numbers. This seems odd but it ends up being really useful . For example, you can use it to do dependency injection where you partially apply your subroutines with dependencies (such as db connection strings or whatever) producing a function that recieves your more dynamic input and running the subroutine with the dependency. ie., something like: ``` getUser :: PostgresConfig -> Id -> IO User ```
You can also write two functions that convert other functions between curried and uncurried forms. Its a pretty good exercise to try out: ``` curry :: ((x, y) -> z) -> x -> y -> z curry = undefined uncurry :: (x -> y -> z) -> (x, y) -> z uncurry = undefined ```
Yep, great description. The book "Haskell Programming From First Principles" (which between you and me I don't really *love* but is unique in several ways) has an excellent chapter on this.
I have to remind myself: Each time I use (if/then/else), check if I should rather use pattern matching or a guard.
Also interesting to follow your thought process on handleEvent. I "cheated" and used Maybe and `orElse` to compose the different potentially event handling use cases (win, move player, move box, change direction, or else keep existing state if any other key was pressed).
On the names: If you have a concrete value like a specific tile, it should have a descriptive name, even in Haskell. But the more abstract a function is, e. g. like mapList, the less descriptive names can be and long names just become a distraction, e. g. `x xs` instead of `firstElement remainingElements`.
I've heard this argument and understand it, but I find that there comes a point where when a token is too short (and "x" and "xs" are good examples of this) my eyes just slide right over it, and this is much more distracting to me than if they had meaningless but recognizable names.
@@TeaLeavesProgramming
Your naming definitely makes sense in this context. I would have done the same :)
In Haskell all functions are implicitly curried. This means that the following to type signatures are the same:
```
moveFromTo :: Coord -> Coord -> Coord -> Coord
moveFromTo :: Coord -> Coord -> (Coord -> Coord)
```
This is one of those things that I could explain on a whiteboard, but somehow when writing code never sticks in my brain, except when I'm doing cutesy "point free" code, and even then it's extra mental effort to get it right.
@@TeaLeavesProgramming A haskell function:
```
add x y = x + y
```
Is constructed internally like this:
```
add = \x -> \y -> x + y
```
or using javascript syntax cause its the universal language:
```
let add = (x) => (y) => x + y
```
Does that help?
So `add` can be seen as a function that takes two numbers and adds them together but realy its a function that takes a number and produces another function that takes a number and then adds the two numbers.
This seems odd but it ends up being really useful . For example, you can use it to do dependency injection where you partially apply your subroutines with dependencies (such as db connection strings or whatever) producing a function that recieves your more dynamic input and running the subroutine with the dependency.
ie., something like:
```
getUser :: PostgresConfig -> Id -> IO User
```
You can also write two functions that convert other functions between curried and uncurried forms. Its a pretty good exercise to try out:
```
curry :: ((x, y) -> z) -> x -> y -> z
curry = undefined
uncurry :: (x -> y -> z) -> (x, y) -> z
uncurry = undefined
```
Yep, great description. The book "Haskell Programming From First Principles" (which between you and me I don't really *love* but is unique in several ways) has an excellent chapter on this.