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 Answers 2

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
Sign up to request clarification or add additional context in comments.

3 Comments

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.
@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).
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'.
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.

Comments