I am new an familiarizing myself to Haskell and yet don't know how to work around problems like this:
I have a zipped (from a Bool
and an Int
list) list of tuples that have (Bool, Int)
form. How can I find index of the (one) element that has values True
as first and 'minimum of the seconds' as second? Is there any fancy library functions I can use?
Since the first element is a Bool
you can filter on it by using just fst
:
filter fst l
In the more general case you'll have a type a
and a predicate p :: a -> Bool
. Then you would filter by composing p
with fst
:
filter (p . fst) l
Now for the second step, you want to find the minimum based on a custom criteria (as opposed to the default compare
). That's exactly what minimumBy
from Data.List does. It expects a comparison function of type (a -> a -> Ordering)
. You can write your own comparison function but there is a better way using on
from Data.Function. To find the minimum element looking at the second elements you would say:
minimumBy (compare `on` snd)
Finding the index is left as an exercise.
I'm guessing your real goal here is to find the value of the minimum, and you can do that without knowing the position of the minimum.
If you need to handle the case of an empty list, then you just return a Maybe type, since the minimum of an empty list is undefined.
Here are two possibilities: getMin, and getMin2
import Data.List (sortBy, foldl')
head' :: [a] -> Maybe a
head' [] = Nothing
head' (a:as) = Just a
getMin :: [(Bool, Int)] -> Maybe (Bool, Int)
getMin vs = head' $ sortBy (\i j -> compare (snd i) (snd j)) $ filter fst vs
getMin2 :: [(Bool, Int)] -> Maybe Int
getMin2 vs = foldl' r Nothing vs where
r (Just i) (b,j) = case (b, compare j i) of
(True, LT) -> Just j
otherwise -> Just i
r Nothing (b,j) = case b of
True -> Just j
False -> Nothing
Data.List> getMin [(True, 4), (False, 0), (True, 3)]
Just (True,3)
Data.List> getMin2 [(True, 4), (False, 0), (True, 3)]
Just 3
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.