Beginner’s question: I have defined these data types:
data State = InStock | BackOrder | Removed
data Part = Part String State
Now I have a large list of parts [parts]
and want to know all parts in this list which are in a particular state:
partsInState :: [Part] -> State -> [Part]
partsInState parts state =
[ p| p <- parts, getState p == state ]
where
getState (Part _ s) = s
That works, but the use of an “getter” function getState
doesn’t look very Haskell-ish.
Is there a better way to do this (maybe without the getter function)?
1 Like
f-a
April 21, 2023, 3:32pm
2
Haskell has (optional) field labels:
data Foo = Foo { fName :: String,
fLength :: Int }
λ> a = Foo "baz" 10
λ> fLength a
10
1 Like
Lsmor
April 21, 2023, 3:54pm
3
Notice you can pattern match directly, without autilixiar function.
partsInState :: [Part] -> State -> [Part]
partsInState parts state = [ p | p@(Part _ s) <- parts, s == state ]
1 Like
jodak
April 21, 2023, 4:00pm
4
I wouldn’t write an extra function for this. Instead use the builtin filter
function and use a named field pState
like @f-a suggested.
filter (\p -> pState p == state) parts
If you still want to have a partsInState
function, you should flip the arguments of this function, so you can do things like:
partsList = undefined :: [[Part]]
map (partsInState state) partsList
Also derive Eq
for your State
type.
1 Like
Wow, the “@” operation looks pretty cool! Or is the @ just part of the name p@
? – Then the magic is in the bracketing (...)
.
Haven’t come across this construct, I think. Any idea where can I read up on it?
2 Likes
The pattern matching syntax in Haskell includes as-patterns , which allow one to simultaneously destructure a value and bind the entire value to a name.
2 Likes
Thanks @jhenahan . This is super cool!
2 Likes