开发者

How to simplify this expression?

开发者 https://www.devze.com 2023-04-11 02:39 出处:网络
Consider this: map fromEnum $ zipWith (==) \"aaaa\" \"abaa\" -- [1,0,1,1] It would be nice to have only one step here:

Consider this:

map fromEnum $ zipWith (==) "aaaa" "abaa"
-- [1,0,1,1]

It would be nice to have only one step here:

zipWith (\x y -> fro开发者_运维百科mEnum (x == y)) "aaaa" "abaa"

Now I can eliminate y:

zipWith (\x -> fromEnum.(x ==)) "aaaa" "abaa"

But I fail to eliminate x. Of course there are ways to "cheat"...

zipWith (curry (fromEnum . uncurry (==))) "aaaa" "abaa"

... but this looks uglier than the original lambda.

The function I look for would be somewhat similar to Data.Function.on, but "the other way around". I have the feeling that there is an embarrassingly simple solution for this. Do I overlook something?


zipWith (\x -> fromEnum . (x ==)) "aaaa" "abaa"

can be written as

zipWith (\x -> (fromEnum .) (x ==)) "aaaa" "abaa"

which can be written as

zipWith ((fromEnum .) . (==)) "aaaa" "abaa"

If you find this readable depends on taste I guess.

EDIT: Another nice way to do it is with some combinators by Matt Hellige:

zipWith ((==) $. id ~> id ~> fromEnum) "aaaa" "abaa"


There are no predefined library functions that do exactly this kind of function composition you want here. But if you are often using constructs like the one in the question, you could define such a function:

(.:) :: (c -> d) -> (a -> b -> c) -> a -> b -> d
g .: f = \x y -> g (f x y)

x = zipWith (fromEnum .: (==)) "aaaa" "abaa"


I have defined following two combinators for prettifying sections of (.):

  1. (|.>): You can read the following definition as, slice f on right and compose with g.

    (|.>) :: (b -> c) -> (a -> a' -> b) -> (a -> a' -> c)
    f |.> g = (f .) . g
    
  2. (<.|): You can read the following definition as, slice g on left and compose with f.

    (<.|) :: (a -> b -> c) -> (a' -> b) -> (a -> a' -> c)
    f <.| g = (. g) . f
    

The direction of arrow indicates the direction in which composition is taking place. Of these two combinators, the first one can be used in your example as follows:

zipWith (fromEnum |.> (==)) "aaaa" "abaa"
0

精彩评论

暂无评论...
验证码 换一张
取 消