简体   繁体   中英

Why is it not possible to define an infix operator via an equation on a section?

Hutton's "Programming in Haskell", first edition, says that the concatenation operator ++ could be defined as:

(++ ys) = foldr (:) ys

This makes logical sense.

I had never seen an operator being defined by an equation on one of its sections (in this case (++ ys) ), so I tried it myself:

(@@) :: [a] -> [a] -> [a]
(@@ ys) = foldr (:) ys

However this doesn't compile, higlighting a syntax error in (@@ ys) .

Has this never been a feature, or has it been removed at some point? If so, why?

I know I could write the above as:

xs @@ ys = foldr (:) ys xs

But I find the point-free style more elegant.

This would result in some subtle inconsistencies. Although we tend to think of curried and flipped and uncurried functions as just different ways of writing the same thing, that is not quite true when it comes to the actual evaluation strategy. Consider

(#>) :: Integer -> Integer -> Integer
(#>) n = let p = {- the `n`-th prime number -} `mod` 74
         in (p+)

Indexing prime numbers is costly. If you write something like

map ((2^43) #>) [100 .. 150]

then the 2 43 -th prime number needs to be computed only once. By contrast, if I define

(<#) :: Integer -> Integer -> Integer
(<#) = flip foo

then writing map (<# (2^43)) [100.. 150] would compute the prime number over and over again, because Haskell doesn't support partially applying functions on the second argument.

With the flip foo definition this isn't too surprising, but if I could have defined the flipped form directly as

(<#n) = let p = {- the `n`-th prime number -} `mod` 74
        in (p+)

then one could reasonably expect that map (<# (2^43)) does share the prime computation, but to support that Haskell's partial evaluation semantics would need to track more information than they currently do, and if we want this to work reliably then it would probably incur some other disadvantages.

I think there's a simpler explanation to do with how complex already are the allowed syntactic forms on lhs of an = binding.

Please always post the error message you're getting, don't just say "higlighting a syntax error". The message might not mean a lot to you, but in this case it gives a strong hint:

(@@ ys) = ...
===> error: Parse error in pattern: @@ys

(xs @@) = ...
===> error: Expression syntax in pattern: xs @@

"in pattern" aha, That is. the lhs is potentially a syntactic pattern; Furthermore there might not be a signature decl for whatever you're introducing, even if there is, the compiler has to check your equation against the signature. so it can't assume anything about the arity of what you're introducing. Consider these valid equations

z         = 42           -- z counts as a pattern
Just z    = {- long and complex expr returning a Maybe, binds z at module-wide scope -}
(Just z)  = {- same same, binds z at module-wide scope -}

foo x     = ...          -- foo gets module-wide scope but not x
(foo x)   = ...          -- same
bar x y   = ...          -- bar gets module-wide scope but not x, y
(bar x) y = ...          -- same

(x ## y) z = ...         -- accepted, introduces triadic operator ##
x ## y z  =              -- rejected error: Parse error in pattern: y
(x ##) y  =              -- rejected error: Expression syntax in pattern: x ##
(## y) z  =              -- rejected error: Parse error in pattern: ##y

The Language Report (section 4.4.3 Function and Pattern Bindings) has

decl   -> (funlhs | pat) rhs
funlhs -> var apat { apat }
        | pat varop pat
        | ( funlhs ) apat { apat }

So the lhs is not a place where expression syntax (incl operator sections) can appear. See also the ugly detail at the end of section 4.4.3.1 to do with using lhs operator syntax in combo with a infix data constructor ugh!

The last sentence here also confirms you can't use operator sections on lhs.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM