简体   繁体   中英

Equivalent of Array.some and Array.every in Haskell?

Something like this type [(a->b)] -> a -> [b] . of course I can code it, but I want to have the correct functional name for it.

Here is the situation:

I'm new to functional programming, and I'm currently using JavaScript for it.

I have an array of predicate functions:

 //predicate :: string -> a -> boolean

 let arr = [ predicate(foo), predicate(bar), predicate(baz) ]

I want to apply them to a value , and get back an array of results:

 let res = [ arr[0](value), arr[1](value), arr[2](value) ]
 // res = [ true ,false, true]

And at the end i want to chain the array using Any.concat or All.concat

 final_result = Any(res[0]).concat(Any(res[1])).concat(Any(res[2])).valueOf()
 // final_result = true | false

Thank you.

In Haskell we have sequence , which specializes to:

sequence :: [a -> b] -> a -> [b]

But I wouldn't use it for the code you showed. Instead I would write one of these:

finalResult = or [predicate x value | x <- arr]
finalResult = any (flip predicate value) arr

Haskell is not category theory. Haskell is Haskell.

Another way to write the functions would be:

import Data.Monoid (Any(..), All (..))
import Data.Coerce

any' :: [a -> Bool] -> a -> Bool
any' = fmap getAny . foldMap (fmap Any)
-- alternatively
any' = fmap getAny . foldMap coerce

and

all' :: [a -> Bool] -> a -> Bool
all' = fmap getAll . foldMap (fmap All)
-- alternatively
all' = fmap getAll . foldMap coerce

Using foldMap , and also optionally coerce to avoid having to write fmap Any or fmap All , which can be inferred from type information elsewhere.

This answer depends of the fact that a function ending on a monoid is itself a monoid:

Monoid b => Monoid (a -> b)

Because Any and All have Monoid instances, a -> Any and a -> All will also have Monoid instances.

mempty:: a -> Any is a function that ignores its input and returns mempty:: Any , which is Any False , the neutral element of the "or" operation. Similarly for a -> All .

mappend:: (a -> Any) -> (a -> Any) -> a -> Any takes two functions, and returns a new function that feeds its own input to each of the previous functions and performs a mappend of the resulting Any s. Similarly for a -> All .

The foldMap function combines the action of mapping over some list—producing values that are instances of Monoid —with the action of mappend ing all the resulting values. In our case we are simply wrapping the "tip" of the functions into Any / All to be able to mappend the functions. Then—somewhat annoyingly—we have to undo the wrapping.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM