| Here's the sample you can play with (interactive: https://play.haskell.org/saved/TWBEYFzH): {-# LANGUAGE RecordWildCards #-}
main =
transport
("2025-09-05T09:00:00Z", "2025-09-05T11:00:00Z")
foo123
kwargs
where
foo123 = Foo
kwargs = Kwargs {..}
bar = Bar
person = Person {..}
name = "Alex Smith"
phone = "+1 (555) 555-5555"
options = Opts {..}
fragile = True
window = PM
data Foo = Foo
data Bar = Bar
data Kwargs = Kwargs
{ bar :: Bar
, person :: Person
, options :: Opts
}
data Person = Person
{ name :: String
, phone :: String
}
data Opts = Opts
{ fragile :: Bool
, window :: HalfDay
}
data HalfDay = AM | PM
transport (start, end)
foo
Kwargs { person = Person{ name = who, ..}, options = Opts{..}, ..}
= do
doStuff who foo
moreStuff phone end window
otherThings start fragile bar
doStuff who foo = print "called doStuff"
moreStuff phone end window = print "called moreStuff"
otherThings start fragile bar = print "calle otherThings"
|
| |
| ▲ | sestep a day ago | parent | next [-] | | I see, so similar to the other languages I mentioned in my post, it looks like Haskell doesn't let you colocate the types with the leaves of the binding form? | | |
| ▲ | instig007 10 hours ago | parent [-] | | > doesn't let you colocate the types with the leaves of the binding form Can you elaborate on the effective difference between colocations in your example and this: transport Kwargs {person = Person{name = who, ..}, options = Opts{..}, ..}
The `Kwargs{..}` alone does imply a non-ambiguous type in the function signature (without explicit but optional annotations), and it binds locally scoped names too. Why doesn't it colocate in the same sense? | | |
| ▲ | sestep 7 hours ago | parent [-] | | It's similar to the Rust example from my post: there are no anonymous records, so in order to be able to construct something with named fields, you need to first define those record types outside. In contrast, my proposed syntax depends on already having anonymous record types like OCaml and TypeScript do, but avoids the extra boilerplate required by separating types from binding forms as shown in my TypeScript example. |
|
| |
| ▲ | instig007 a day ago | parent | prev [-] | | To address the example towards the end of your post, if you want patterns + struct binding at the same time, prefix patterns with `bindName@`, for instance: transport
myTuple@(start, end)
foo
kwargs@(Kwargs { person = Person{ name = who, ..}, options = Opts{..}, ..})
= do
...
|
|