2

As is known:

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

I can use this compound operator prefix-style like this:

((.).(.)) f g

But it appears I cannot use it infix like this:

f ((.).(.)) g

Is there a way to use this infix style without defining another operator or using a predefined one in a package?

2 Answers2

4

No you can't.

Only two kinds of infix operator exist in haskell:

  1. A single token that is one or more operator symbols. For all the operator symbols please read What characters are permitted for haskell operators?
  2. A single identifier between two backticks. An identifier is a token that satisfies certain conditions: please read https://www.haskell.org/onlinereport/haskell2010/haskellch2.html#x7-180002.4

So <$> is a legal infix operator, and `f`, but not `f x`. To test if something is a single token try lex "YOUR_TOKEN". It's a good test with three exceptions (reference from the documentation of Prelude):

  • Qualified names are not handled properly
  • Octal and hexadecimal numerics are not recognized as a single token
  • Comments are not treated properly
Community
  • 1
  • 1
zakyggaps
  • 3,070
  • 2
  • 15
  • 25
  • What's interesting is this: `:t ((.).(.)) undefined undefined` yields `((.).(.)) undefined undefined :: a -> a1 -> c` and `:t undefined (.).(.) undefined` yields `undefined (.).(.) undefined :: (a -> b) -> c` in GHCI. –  Feb 19 '16 at 08:17
  • 1
    @Ana This one is even more complicated. An operator in `()` are treated as a normal named function, also function application (white space) has higher precedence than function composition `.`, so `undefined (.) . (.) undefined` is actually `(undefined (.)) . ((.) undefined)`. – zakyggaps Feb 19 '16 at 08:28
  • In `undefined (.)`, `undefined` is expanded to `((b -> c) -> (a -> b) -> (a -> c)) -> v'` where `v'` is free, so `undefind (.)` has type `v'` just like `undefined` itself. In `(.) undefined`, `undefined` is expanded to `b' -> c'` so `(.) undefined` is resolved to type `(a' -> b') -> (a' -> c')`, by applying the middle `.` `v'` expended to `(a' -> c') -> r'`, so the result type is in form `(a' -> b') -> r'`. – zakyggaps Feb 19 '16 at 08:45
3

No, you can't. An infix operator can only be either

  • An actual named infix. Indeed it's common to define

    (.:) :: (c->d) -> (a->b->c) -> a->b->d
    (.:) = (.).(.)
    

    locally.

  • A named function in backticks.

leftaroundabout
  • 117,950
  • 5
  • 174
  • 319