Functional dependencies *not* part of the next Haskell standard?

I tried to do something in CAL that I could not solve without functional dependencies. In their support forum, it got mentioned that func.deps propably won't make into the next Haskell standard... Any comments on that? Now, the thing I tried to solve was: data Vector2 a = Num a => V2 a a class Vector a n | a -> n where dot :: a -> a -> n instance Num a => Vector (Vector2 a) a where dot (V2 x1 y1) (V2 x2 y2) = x1 * x2 + y1 * y2 test1 = dot (V2 1.0 2.0) (V2 3.0 4.0) Please note this is just some testing code (the math people in here might be horrified by it ;), although any hints of how to do this in a clearer way are welcome. As side-note, does Haskell have some easy to use good linear algebra package for doing 2D, 3D and 4D math? Then I would not be writing any of this code, although I did find it useful for learning. Now without the funcdep a -> n in the type class declaration I get No instance for (Vector (Vector2 t) n) arising from use of `dot' at l:/Haskell/test/vector.hs:9:8-36 Possible fix: add an instance declaration for (Vector (Vector2 t) n) In the expression: dot (V2 1.0 2.0) (V2 3.0 4.0) In the definition of `test1': test1 = dot (V2 1.0 2.0) (V2 3.0 4.0) CAL seems to have the same problem, and without funcdeps I seem to be stuck in that language. PS(1): In the above I was using GHCI with extensions enabled. PS(2): IMHO CAL is in some aspects easier to get started than Haskell because of their nice Eclipse plugin and GEM Cutter environment for doing learning experiments. Thanks, Peter

On Thu, 12 Jul 2007, peterv wrote:
I tried to do something in CAL that I could not solve without functional dependencies. In their support forum, it got mentioned that func.deps propably won't make into the next Haskell standard... Any comments on that?
Now, the thing I tried to solve was:
data Vector2 a = Num a => V2 a a
class Vector a n | a -> n where dot :: a -> a -> n
instance Num a => Vector (Vector2 a) a where dot (V2 x1 y1) (V2 x2 y2) = x1 * x2 + y1 * y2
test1 = dot (V2 1.0 2.0) (V2 3.0 4.0)
class Vector v where dot :: Num a => v a -> v a -> a instance Vector Vector2 where dot (V2 x1 y1) (V2 x2 y2) = x1 * x2 + y1 * y2 This will work satisfyingly if you don't plan a larger type class hierarchy.

instance Vector Vector2 where dot (V2 x1 y1) (V2 x2 y2) = x1 * x2 + y1 * y2
I tried to do something in CAL that I could not solve without functional dependencies. In their support forum, it got mentioned that func.deps propably won't make into the next Haskell standard... Any comments on
Amazing, so simple it is, Yoda would say ;) I did not realize one could perform "partial application" on types when declaring instances (I mean not specifying the type of Vector2 in <instance Vector Vector2>). Now regarding these funcdeps, are they "ill" as the "rumor" goes? Thanks, Peter -----Original Message----- From: Henning Thielemann [mailto:lemming@henning-thielemann.de] Sent: Thursday, July 12, 2007 11:44 AM To: peterv Cc: Haskell-Cafe@haskell.org Subject: Re: [Haskell-cafe] Functional dependencies *not* part of the next Haskell standard? On Thu, 12 Jul 2007, peterv wrote: that?
Now, the thing I tried to solve was:
data Vector2 a = Num a => V2 a a
class Vector a n | a -> n where dot :: a -> a -> n
instance Num a => Vector (Vector2 a) a where dot (V2 x1 y1) (V2 x2 y2) = x1 * x2 + y1 * y2
test1 = dot (V2 1.0 2.0) (V2 3.0 4.0)
class Vector v where dot :: Num a => v a -> v a -> a instance Vector Vector2 where dot (V2 x1 y1) (V2 x2 y2) = x1 * x2 + y1 * y2 This will work satisfyingly if you don't plan a larger type class hierarchy.

peterv wrote:
instance Vector Vector2 where dot (V2 x1 y1) (V2 x2 y2) = x1 * x2 + y1 * y2
Amazing, so simple it is, Yoda would say ;)
I did not realize one could perform "partial application" on types when declaring instances (I mean not specifying the type of Vector2 in <instance Vector Vector2>).
Now regarding these funcdeps, are they "ill" as the "rumor" goes?
I don't think there is any danger of them being removed and not replaced. The functionality is useful. Associated Types is widely viewed as a successor/replacement, but no complete implementation exists yet: http://haskell.org/haskellwiki/GHC/Indexed_types I'm sure FDs are here for a while yet. Jules

jules:
peterv wrote:
instance Vector Vector2 where dot (V2 x1 y1) (V2 x2 y2) = x1 * x2 + y1 * y2
Amazing, so simple it is, Yoda would say ;)
I did not realize one could perform "partial application" on types when declaring instances (I mean not specifying the type of Vector2 in <instance Vector Vector2>).
Now regarding these funcdeps, are they "ill" as the "rumor" goes?
I don't think there is any danger of them being removed and not replaced. The functionality is useful.
Associated Types is widely viewed as a successor/replacement, but no complete implementation exists yet:
I think the implementation is some 90% complete though, in GHC head. Certainly you can write many associated types programs already -- the missing part is finishing off associated type synonyms, iirc. -- Don

| I think the implementation is some 90% complete though, in GHC head. | Certainly you can write many associated types programs already -- the | missing part is finishing off associated type synonyms, iirc. ...and we have a working implementation of that too, thanks to Tom Schrijvers. It's not in the HEAD yet, but it will be in a few weeks. Simon

Hello Simon, Friday, July 13, 2007, 11:37:59 AM, you wrote:
| I think the implementation is some 90% complete though, in GHC head. | Certainly you can write many associated types programs already -- the | missing part is finishing off associated type synonyms, iirc.
...and we have a working implementation of that too, thanks to Tom Schrijvers. It's not in the HEAD yet, but it will be in a few weeks.
so it will be a part of 6.8? great news! afaiu, ATS, rather than AT, is direct substitution for FD? -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

bulat.ziganshin:
Hello Simon,
Friday, July 13, 2007, 11:37:59 AM, you wrote:
| I think the implementation is some 90% complete though, in GHC head. | Certainly you can write many associated types programs already -- the | missing part is finishing off associated type synonyms, iirc.
...and we have a working implementation of that too, thanks to Tom Schrijvers. It's not in the HEAD yet, but it will be in a few weeks.
so it will be a part of 6.8? great news! afaiu, ATS, rather than AT, is direct substitution for FD?
Functional dependencies desugar to indexed type families, an extension of the original associated, in GHC head already. For the full story, see the wiki page. http://haskell.org/haskellwiki/GHC/Indexed_types which includes an example of porting functional dependencies to associated types http://haskell.org/haskellwiki/GHC/Indexed_types#A_associated_type_synonym_e... -- Don

| I think the implementation is some 90% complete though, in GHC head. | Certainly you can write many associated types programs already -- the | missing part is finishing off associated type synonyms, iirc.
...and we have a working implementation of that too, thanks to Tom Schrijvers. It's not in the HEAD yet, but it will be in a few weeks.
so it will be a part of 6.8? great news! afaiu, ATS, rather than AT, is direct substitution for FD?
Functional dependencies desugar to indexed type families, an extension of the original associated, in GHC head already. For the full story, see the wiki page.
http://haskell.org/haskellwiki/GHC/Indexed_types
which includes an example of porting functional dependencies to associated types
http://haskell.org/haskellwiki/GHC/Indexed_types#A_associated_type_synonym_e...
It's really simple to replace a functional dependency with a type function. A class declaration class C a b | a -> b becomes: class FD a ~ b => C a b where type FD a and an instance instance C [x] x becomes instance C [x] x where type FD [x] = x That's it: only class and instance declarations have to be modified. Now you can start to drop dependent parameters, if you want. There are a few examples in my slides as well (if you don't mind the pptx): http://www.cs.kuleuven.be/~toms/Research/talks/Tyfuns.pptx Cheers, Tom -- Tom Schrijvers Department of Computer Science K.U. Leuven Celestijnenlaan 200A B-3001 Heverlee Belgium tel: +32 16 327544 e-mail: tom.schrijvers@cs.kuleuven.be

Simon Peyton-Jones wrote:
| I think the implementation is some 90% complete though, in GHC head. | Certainly you can write many associated types programs already -- the | missing part is finishing off associated type synonyms, iirc.
...and we have a working implementation of that too, thanks to Tom Schrijvers. It's not in the HEAD yet, but it will be in a few weeks.
Excellent news! Jules

2007/7/12, peterv
Amazing, so simple it is, Yoda would say ;)
I did not realize one could perform "partial application" on types when declaring instances (I mean not specifying the type of Vector2 in <instance Vector Vector2>).
You ought to meditate on the type class 'Monad,' then, which was the motivating example for allowing these kinds of classes in standard Haskell ;-) All the best, - Benja

Thanks for the advice. I did not really deeply investigate the monad type
classes yet...
It looks like its gonna take a long time for me to learn Haskell. I'm not
sure if my long history of imperative and object-oriented programming has
something to do with it. Reading Haskell books like SOE is one thing, but
writing software in Haskell is really difficult for me. Not only do I miss
the "spoiled OO programmer" IDEs with all their candy and code completion
and assistants, but I also get the feeling that although similar programs in
Haskell or typically N times shorter than their imp/OO counterparts, it
would take *me* at least N^2 longer to write them ;) (now I must admit I had
the same feeling when switching from 680x0 assembler to C++, but let's say
N*2 longer instread of N^2...) Is this true for Haskell in general? I mean
how long do experienced Haskell developers spent writing code "to get it
right" (excluding minor bugs and performance issues)? Or do they write down
Haskell fluently?
Regarding those monads, I read a lot of stuff about these beast, trying to
get a high-level understanding about them (and apparently I'm not the only
newby who struggled with that ;), but after having read "You Could Have
Invented Monads!" and then reading
http://research.microsoft.com/~simonpj/papers/marktoberdorf, it all became
much clearer. Those pictures really helped...
Monads were very confusing because I first looked at Concurrent Clean (it
comes with an IDE and games! :), and that language uses a simple "uniqueness
typing" approach where the "world" or "state" is explicitly passed as an
object, and where the compiler garantees "monadic" usage of that object
(warning: that was a lot of fuzzy talk from a newbie trying to look
impressive ;)
-----Original Message-----
From: Benja Fallenstein [mailto:benja.fallenstein@gmail.com]
Sent: Thursday, July 12, 2007 3:11 PM
To: peterv
Cc: Henning Thielemann; Haskell-Cafe@haskell.org
Subject: Re: [Haskell-cafe] Functional dependencies *not* part of the next
Haskell standard?
2007/7/12, peterv
Amazing, so simple it is, Yoda would say ;)
I did not realize one could perform "partial application" on types when declaring instances (I mean not specifying the type of Vector2 in <instance Vector Vector2>).
You ought to meditate on the type class 'Monad,' then, which was the motivating example for allowing these kinds of classes in standard Haskell ;-) All the best, - Benja

Hello peterv, Thursday, July 12, 2007, 6:01:43 PM, you wrote:
Monads were very confusing because I first looked at Concurrent Clean (it comes with an IDE and games! :), and that language uses a simple "uniqueness typing" approach where the "world" or "state" is explicitly passed as an object, and where the compiler garantees "monadic" usage of that object
btw, internally most haskell compilers do the same and monad syntax is just syntax sugar above this. look at http://haskell.org/haskellwiki/IO_inside to complete the picture. and ST monad does the same too -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

On Thu, 2007-07-12 at 16:01 +0200, peterv wrote:
Thanks for the advice. I did not really deeply investigate the monad type classes yet...
It looks like its gonna take a long time for me to learn Haskell. I'm not sure if my long history of imperative and object-oriented programming has something to do with it. Reading Haskell books like SOE is one thing, but writing software in Haskell is really difficult for me. Not only do I miss the "spoiled OO programmer" IDEs with all their candy and code completion and assistants, but I also get the feeling that although similar programs in Haskell or typically N times shorter than their imp/OO counterparts, it would take *me* at least N^2 longer to write them ;) (now I must admit I had the same feeling when switching from 680x0 assembler to C++, but let's say N*2 longer instread of N^2...) Is this true for Haskell in general? I mean how long do experienced Haskell developers spent writing code "to get it right" (excluding minor bugs and performance issues)? Or do they write down Haskell fluently?
Skilled Haskell programmers write Haskell fluently, but I'd say that that still tends to require more thought per line on average than a typical imperative language. A single line of Haskell tends to do a heck of a lot more than a single line of mainstream imperative languages. Usually, though, once you get a nice base encoding your domain concepts, things move faster. The more code you write the -less- thinking you should need to do relative to imperative languages. Haskell code complexity grows (much) slower with size as compared to most imperative languages.

peterv wrote:
It looks like its gonna take a long time for me to learn Haskell. I'm not sure if my long history of imperative and object-oriented programming has something to do with it. Reading Haskell books like SOE is one thing, but writing software in Haskell is really difficult for me.
It takes practice. ;-)
Not only do I miss the "spoiled OO programmer" IDEs with all their candy and code completion and assistants
Ah, but in Haskell, you don't need to *write* as much code in the first place! :-D
but I also get the feeling that although similar programs in Haskell or typically N times shorter than their imp/OO counterparts, it would take *me* at least N^2 longer to write them ;) Is this true for Haskell in general?
Yeah, Haskell is definitely *not* a language for "hacking away as fast as your fingers can type without thinking too much". It's more like a game of chess - you spend a lot of time trying to bend your mind around the best way to achieve a thing. But then, when you actually start typing, you often get there faster. Or realise that the type system is going to stop you... :-/
Regarding those monads, I read a lot of stuff about these beast, trying to get a high-level understanding about them (and apparently I'm not the only newby who struggled with that ;), but after having read "You Could Have Invented Monads!" and then reading http://research.microsoft.com/~simonpj/papers/marktoberdorf, it all became much clearer. Those pictures really helped...
Monads take a while to "get used to", but they're not so scary after that...

On 7/12/07, Andrew Coppin
Monads take a while to "get used to", but they're not so scary after that...
The problem with monads is that there is a gazillion tutorials to explain them, each with their own analogy that works well for the author but not necessarily for you. It adds to the complexity of something that is indeed, not so difficult after all.

D.V. wrote:
On 7/12/07, Andrew Coppin
wrote: Monads take a while to "get used to", but they're not so scary after that...
The problem with monads is that there is a gazillion tutorials to explain them, each with their own analogy that works well for the author but not necessarily for you.
It adds to the complexity of something that is indeed, not so difficult after all.
What was the phrase? "Monads are possibly the most tutorialised concept ever..."? Still, while the concept is simple, it's hard to sum up in just a few words what a monad "is". (Especially given that Haskell has so many different ones - and they seem superficially to bear no resemblence to each other.) Maybe I'll give it a shot some day. ;-)

On Saturday 14 July 2007 05:21, Andrew Coppin wrote:
Still, while the concept is simple, it's hard to sum up in just a few words what a monad "is". (Especially given that Haskell has so many different ones - and they seem superficially to bear no resemblence to each other.)
Well, how about this as a starting point (from a post i wrote in my blog): "[In Haskell,] a monad simply seems to be a computational environment in which one can specify that certain types and methods of computation be performed, and in which the three monad laws are expected to hold." What do people think? With regards to the last phrase, i seem to recall that there are monads which nevertheless actually /don't/ follow all three monad laws? Alexis.

Alexis Hazell wrote:
On Saturday 14 July 2007 05:21, Andrew Coppin wrote:
Still, while the concept is simple, it's hard to sum up in just a few words what a monad "is". (Especially given that Haskell has so many different ones - and they seem superficially to bear no resemblence to each other.)
Well, how about this as a starting point (from a post i wrote in my blog):
"[In Haskell,] a monad simply seems to be a computational environment in which one can specify that certain types and methods of computation be performed, and in which the three monad laws are expected to hold."
What do people think?
Hmm... it doesn't leave me with either a strong sense of "oh, that sounds simple" or "oh, I understand what that means". I'm only one guy of course...
With regards to the last phrase, i seem to recall that there are monads which nevertheless actually /don't/ follow all three monad laws?
That is my recollection also. (Don't ask me *which* monads, mind you...) In the case in point, the law breakage never the less matches "intuition"; personally, I ignore the monad laws on the basis that if you're doing something "sane", the laws will automatically hold anyway. (But maybe I'm just a renegade?)

On 7/14/07, Andrew Coppin That is my recollection also. (Don't ask me *which* monads, mind you...)
In the case in point, the law breakage never the less matches
"intuition"; personally, I ignore the monad laws on the basis that if
you're doing something "sane", the laws will automatically hold anyway.
(But maybe I'm just a renegade?) Yeah, the laws confused me for a while as well. Hint to guys writing
Haskell documentation, we're not all doing CS phD you know ;-) We just want
to get things done ;-)
Andrew, I found comfort and explanation in this article
http://www.haskell.org/haskellwiki/Monads_as_containers :
"The functions return and bind need to satisfy a few
lawshttp://www.nomaware.com/monads/html/laws.html#lawsin order to
make a monad, but if you define them in a sensible way given
what they are supposed to do, the laws will work out. The laws are only a
formal way to give the informal description of the meanings of return and
bind I have here."

Hugh Perkins wrote:
On 7/14/07, *Andrew Coppin*
That is my recollection also. (Don't ask me *which* monads, mind you...) In the case in point, the law breakage never the less matches "intuition"; personally, I ignore the monad laws on the basis that if you're doing something "sane", the laws will automatically hold anyway. (But maybe I'm just a renegade?)
Yeah, the laws confused me for a while as well. Hint to guys writing Haskell documentation, we're not all doing CS phD you know ;-) We just want to get things done ;-)
Andrew, I found comfort and explanation in this article http://www.haskell.org/haskellwiki/Monads_as_containers :
"The functions return and bind need to satisfy a few laws http://www.nomaware.com/monads/html/laws.html#laws in order to make a monad, but if you define them in a sensible way given what they are supposed to do, the laws will work out. The laws are only a formal way to give the informal description of the meanings of return and bind I have here."
Oh, I *understand* the laws - I just think that if you're trying to explain how to *use* (not *write*) monads, you really don't need to emphasize this "laws" business. IMHO...

On Sat, 2007-07-14 at 20:58 +0200, Hugh Perkins wrote:
On 7/14/07, Andrew Coppin
That is my recollection also. (Don't ask me *which* monads, mind you...) In the case in point, the law breakage never the less matches "intuition"; personally, I ignore the monad laws on the basis that if you're doing something "sane", the laws will automatically hold anyway. (But maybe I'm just a renegade?)
Yeah, the laws confused me for a while as well. Hint to guys writing Haskell documentation, we're not all doing CS phD you know ;-) We just want to get things done ;-)
-Documentation- damn well better have the monad laws. Something is not a monad if it does not satisfy the monad laws. Furthermore, the monad laws are almost the only thing that -does- define monads.

Well, can you provide an example of an implementation of bind that satisfies
an intuitive definition of bind but does not satisfy the monad laws?
On 7/14/07, Derek Elkins
-Documentation- damn well better have the monad laws. Something is not a monad if it does not satisfy the monad laws. Furthermore, the monad laws are almost the only thing that -does- define monads.

ListT IO (http://www.haskell.org/hawiki/ListTDoneRight) On Sat, 2007-07-14 at 21:34 +0200, Hugh Perkins wrote:
Well, can you provide an example of an implementation of bind that satisfies an intuitive definition of bind but does not satisfy the monad laws?
On 7/14/07, Derek Elkins
wrote: -Documentation- damn well better have the monad laws. Something is not a monad if it does not satisfy the monad laws. Furthermore, the monad laws are almost the only thing that -does- define monads.

Yeah, the laws confused me for a while as well. Hint to guys writing Haskell documentation, we're not all doing CS phD you know ;-) We just want to get things done ;-)
teachers and tutorials making a fuss about some concept is the surest way to guarantee that learners will find that concept difficult (holds for Monads, functional i/o, Monad laws, Turing machines, higher order functions, and many other things [*]). the Monad type class tells you the interface (what operations you've got, and their types), the Monad laws tell you what all types implementing that interface should have in common. it is all just about getting things done!-) the monadic interface gives you two operations, one to throw things into a monad thing, and one to chain two monad things together. the monad laws tell you two useful facts about monad things thrown together in that way: whatever it is the monad does, anything just thrown into it will take no part in that action, and whichever way you use that chaining operation, the structure of chaining is irrelevant, only the ordering of chained monad things matters. hth?-) claus [*] digging out the original paper can often be surprisingly enlightening, in the algol way of the original being an improvement on all its successors. [**] "thing" is a technical term that would take too long to explain, closely related to those "apples" mentioned in another thread;-)

Claus Reinke wrote:
teachers and tutorials making a fuss about some concept is the surest way to guarantee that learners will find that concept difficult
Definitely has a ring of truth to it...
the monadic interface gives you two operations, one to throw things into a monad thing, and one to chain two monad things together.
...and *that* is quite possibly the simplest and clearest way to explain just what a monad is. Explaning why this is useful for anything takes a little longer. ;-)

On Fri, 2007-07-13 at 15:08 +0200, D.V. wrote:
On 7/12/07, Andrew Coppin
wrote: Monads take a while to "get used to", but they're not so scary after that...
The problem with monads is that there is a gazillion tutorials to explain them, each with their own analogy that works well for the author but not necessarily for you.
It adds to the complexity of something that is indeed, not so difficult after all.
Agreed. More strongly, the main problem with monads nowadays is that there are gazillions of -bad- tutorials and only a few decent ones. Back in the day, when there were only a few tutorials, the main problem was people generalizing to quickly from particular instances. Those people went on to write monad tutorials. I think I'll make a "not monad" tutorial about what monads are not.

Hello peterv, Thursday, July 12, 2007, 6:01:43 PM, you wrote:
Haskell or typically N times shorter than their imp/OO counterparts, it would take *me* at least N^2 longer to write them ;) (now I must admit I had the same feeling when switching from 680x0 assembler to C++, but let's say N*2 longer instread of N^2...) Is this true for Haskell in general?
there is well-known observation that programmer productivity, measured in lines of code, doesn't depend on the language ;) the difference between my coding styles in C and Haskell (both fluent, unlike English ;) is that after i've understood algorithm i want to implement, i write it immediately in Haskell, and write a tons of boilerplate code in C Haskell allows to easily write much more complex algorithms and this may trick you - you tend to implement more complex algorithms in Haskell and this, naturally, leads to the fact that you think much more while programming in Haskell. try to implement algorithm of the same complexity in C and Haskell and compare processes -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

Hello peterv, Thursday, July 12, 2007, 5:03:29 PM, you wrote:
I did not realize one could perform "partial application" on types when declaring instances (I mean not specifying the type of Vector2 in <instance Vector Vector2>>).
this feature, called "constructor classes" was in Haskell since 1.2 or 1.3 version. you can find more info about it here: http://www.haskell.org/haskellwiki/Research_papers/Type_systems#Type_classes in particular, i suggest you to read "Type classes: exploring the design space" -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

peterv
I tried to do something in CAL that I could not solve without functional dependencies. In their support forum, it got mentioned that func.deps propably won't make into the next Haskell standard... Any comments on that?
Here's a link "CAL for Haskell Programmers" for anyone who wondered like myself... http://quarkframework.blogspot.com/2006/09/cal-for-haskell-programmers.html Functional dependencies were one of the first extensions I found a need to learn, starting out in Haskell, as part of the crucial extension "multiparameter type classes" which wouldn't work for me without functional dependencies. I then rewrote my code to avoid all of that, something one should always consider doing. I'd still miss them in principle, and in practice I'd expect to see them or something better survive in GHC, my lone axe. Maybe a certain conservatism in the language standards is ok, and something better will come along. Wouldn't want people in 2017 seeing this construct and having it read to them like the word "groovy".
participants (15)
-
Alexis Hazell
-
Andrew Coppin
-
Benja Fallenstein
-
Bulat Ziganshin
-
Claus Reinke
-
D.V.
-
Dave Bayer
-
Derek Elkins
-
dons@cse.unsw.edu.au
-
Henning Thielemann
-
Hugh Perkins
-
Jules Bean
-
peterv
-
Simon Peyton-Jones
-
Tom Schrijvers