4 ms·
I know it's a minor thing, but why do people keep coppying this annoying Haskell/ML pattern where I have to type twice the name of a function if I want to expli
by nnq 11y ago
I know it's a minor thing, but why do people keep coppying this annoying Haskell/ML pattern where I have to type twice the name of a function if I want to explicitly define it's type?
current :: IO String
current = ...
(yeah, it's a minor issue compared to the uber-annoying problem of 'name clashes in record fields' https://wiki.haskell.org/Name_clashes_in_record_fields https://wiki.haskell.org/Name_clashes_in_record_fields ...but still)
- nightski 11y agoI personally find it incredibly clean. You separate the type signature from the implementation (mostly because a lot of the times it is unnecessary from the compiler's pov, but useful as documentation). To that end, I don't see it as any different from a javadoc or any kind of code documentation. In addition since Haskell supports multiple case defitions at the top level inline type declarations would be redundant. For example - current a 0 :: IO Int Int -> Int current 0 b :: IO Int Int -> Int current 0 0 :: IO Int Int -> Int vs. current :: IO Int Int -> Int current 0 a = ... current a 0 = ... current 0 0 = ...
- tome 11y agoWhat syntax do you propose?
- nnq 11y agoThis is the most obvious that comes to mind: current :: IO String : = do d <- Date.new () -- reads system timer, hence IO d.toString ...or for something that works better with a really huge type signature or list of arguments, you could extend it like this myFunctionFoo :: Int -> Int -> Int -> Int : a b c = 2*a + 3*b + 4*c
- reirob 11y agoThanks for the proposals. How would you make your first variant, work with pattern matching? I like the second variant better, because it seems to work with pattern matching. It would as well have to work without type declarations, letting Haskell infer the types. But all in all I prefer the way function definition is implemented now. The record issue is more of a trouble - for it Frege actually has some improvements.
- nnq 11y agoThanks for examining the proposals. All in all I don't think improving this bit of syntax would actually mean this much, it's only worth considering when you start a new language from scratch. But the records names / TDNR issue, this makes a real difference, I'll definitely take a look at Frege if I'll need functional programming on the JVM ...as Scala just seems too scary for me. Now, about what I proposed above, I meant the two examples as different cases of the same syntax, newlines should not really make a difference until after the "=". So you'd use the second variant for pattern matching: myFunctionFoo :: Int -> Int -> Int -> Int : 1 b c = 1984 - c : a b c = 2*a + 3*b + 4*c But it's probably better to direct your effort elsewhere. I see that even Typed Clojure prefers to repeat the name of a symbol instead of bothering to rearrange everything else just to avoid this repetition. ...and it's probably not worth spoiling the beauty of the ML-style-syntax for this. I admit it, I find it 10x easier to read either Lisps or C-syntax-like languages than MLs, but there is a beauty in the ML way, and math folks seem to love it, so better keep it that way :)
- voxfrege 11y agoActually, you can write: foo = (\a -> \b -> (a+b)*(a-b)) :: Num z => z -> z -> z HOwever, it is quite un-idiomatic, of course.