Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Idiomatic way to fetch the first occurrence of a specific constructor from a list

Tags:

haskell

Is there a nice way to find the first occurrence of a constructor in a list, without the explicit recursion in the sample below?

data Elem = A Int | B Char deriving Show

getA :: [Elem] -> Maybe Elem
getA [] = Nothing
getA (e:es) = 
    case e of 
        A a -> Just (A a)
        _   -> getA es
like image 909
martingw Avatar asked Nov 19 '11 15:11

martingw


2 Answers

Simply

import Data.Maybe (listToMaybe)
getA xs = listToMaybe [e | e@(A _) <- xs]

Addendum: even better, future-proofed using an empty record pattern (kudos hammar):

getA xs = listToMaybe [e | e@(A{}) <- xs]

Note however, that this only works out so neatly for matching constructors. For general properties, find is nicer:

get prop xs = listToMaybe [e | e <- xs, prop e]
get prop xs = listToMaybe (filter prop xs)
get prop xs = find prop xs
like image 174
Daniel Fischer Avatar answered Nov 17 '22 14:11

Daniel Fischer


You can use Data.List.find.

getA = find isA
   where isA (A {}) = True
         isA _ = False
like image 11
hammar Avatar answered Nov 17 '22 13:11

hammar