According to Hoogle, the fixity of <=<
(Kleisli monad composition, or "left fish") and =<<
(reverse monad bind) is infixr 1
. If I'm looking at them correctly, an expression like, say
print <=< return =<< return "foo"
should be invalid, since it would've been equivalent to the equally invalid
print <=< (return =<< return "foo")
But for some reason, though the first expression seems to be invalid in Haskell, as expected, Frege seems to have no complaints, and evaluates <=<
before the =<<
.
I discovered this when I was messing around on pointfree.io to figure out how to make something like
foo >>= (bar <=< baz)
point-free, and it gave me
bar <=< baz =<< foo
which doesn't look quite right, considering the fixities.
Frege is like Haskell, but Frege is not Haskell. And in Frege, the fixities of those operators are different: =<<
is infixr 2
and <=<
is infixr 3
. So since <=<
has lower precedence, bar <=< baz =<< foo
is naturally parsed as (bar <=< baz) =<< foo
.
(In fact, =<<
and <=<
have different types in Frege than they do in Haskell: instead of a Monad
constraint, they have a Bind
constraint, where Bind
is like Monad
without pure
/return
.)
Yes, Frege describes itself as "a Haskell for the JVM", but they mean "a Haskell" in the sense that Common Lisp is a Lisp, and Scheme is a Lisp, and Clojure is a Lisp. It's odd to see "Haskell" used in that way; it would be more normal to see "a Haskell-like language for the JVM", or something stronger. But Frege is so similar that I can see why.
Also, you're right: that does appear to be a bug in pointfree
(the program that backs pointfree.io)! pointfree
is supposed to generate Haskell code, not Frege, so the fact that that transformation is invalid means it's doing the wrong thing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With