Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

It's a nuanced issue, because Haskell extensively uses the dot (.) infix operator to mean function composition. Currently, the expression `f.g` will attempt to compose the function bound to `f` with the function bound to `g`.


It's worth pointing out that Haskell has always overloaded the dot. It is used for module namespace disambiguation, e.g Set.fromList


Great point! I hadn't thought of this.

It looks like the "record dot" follows the same parsing rules as the "module dot": the presence of whitespace turns the . into function composition.


But you've got the module there to disambiguate the ., which you don't have in records.


I don't think this is true. The presence of a qualified import of "Data.Set as Set" does not change how the following is parsed.

    import Data.Set (fromList)
    import qualified Data.Set as Set


    data Set a = Set (Set.Set a)

    f :: Ord a => [a] -> Set a
    f = Set . fromList

    g :: Ord a => [a] -> Set a
    g = Set .fromList

    h :: Ord a => [a] -> Set a
    h = Set. fromList

    i :: Ord a => [a] -> Set.Set a
    i = Set.fromList
In other words, the . is interpreted as a "module dot" if and only if there is no whitespace either preceding or following the dot.


> Currently, the expression `f.g` will attempt to compose the function bound to `f` with the function bound to `g`.

So what will this mean now? Will function composition require a space between the dot, or how will a “record dot” be disambiguated?


From https://github.com/ghc-proposals/ghc-proposals/blob/master/p...

.g is a field selector.

f.g is field selection of a record.

f . g is function composition.

f. g is function composition.


Whilst I'm not going to argue the proposal is a bad thing, I think you've just summarized why some are giving it the side eye pretty well.


To me it's just, "the dot hugs a field, dot by itself is composition, and module names are capitalized."

While I wouldn't write f. g, if I see it, it's not hugging the field name so it's composition. I don't think I'd have trouble reading it.

But... it will probably trip up newbies and people with odd spacing styles. Hopefully GHC can give a useful error like "In the field selection expression f.g, g is a function defined on XX. Did you mean f . g?"


(.g) us a field selector, is (. g) then a function :: (a -> b) -> c -> b?


Yep! You could check this in GHCi (the repl), for example:

  > :t (. id)
  > (. id) :: (b -> c) -> b -> c
(:t prints the type of an expression, and id is the "identity function" that's b -> b here.)

(EDIT: Maybe you know the above and you're asking if it's being changed in the proposal. It doesn't seem so to me.)


I'm just pointing out that the difference between (.g) and (. g) is potentially easy to miss.




Consider applying for YC's Summer 2026 batch! Applications are open till May 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: