Оператор точки в haskell с многопараметрическими функциями

Я хочу написать функцию без точек в haskell, чтобы все было просто, скажем, я хочу сделать эту функцию:

maxmin :: Ord a => a -> a -> a -> a
maxmin a b c = max a (min b c)

Я могу улучшить это до

maxmin a b = (max a) . (min b)

но есть ли способ избавиться от a и b?


person Erik Henriksson    schedule 20.11.2012    source источник
comment
Бесточечное кодирование — это стиль кода, поэтому его следует использовать только тогда, когда это улучшает читабельность; случаи, когда безточечная нотация компилируется по-другому (из-за встраивания), в целом не о чем вам нужно беспокоиться (подумайте об этом после профилирования). В вашем случае я бы сказал, что безточечный режим не помогает; Например, переименование maxmin в constrainTo было бы гораздо более выразительным изменением.   -  person David    schedule 20.11.2012


Ответы (2)


Я бы не сказал, что это проще, но вот:

maxmin :: Ord a => a -> a -> a -> a                                             
maxmin = (. min) . (.) . max 

(Создано с помощью инструмента pl из lambdabot http://www.haskell.org/haskellwiki/Pointfree)

lambdabot> pl maxmin a b c = max a (min b c)
maxmin = (. min) . (.) . max
person applicative_functor    schedule 20.11.2012

Вы просто используете для этого "три закона секций",

(a `op` b) = (a `op`) b = (`op` b) a = op a b

так что

import Control.Arrow

maxmin a b = (max a) . (min b)
           = (.) (max a) (min b)
           = uncurry (.) (max a, min b)
           = uncurry (.) . (max *** min) $ (a, b)
           = curry (uncurry (.) . (max *** min)) a b

что тоже не слишком читабельно. :)

person Will Ness    schedule 20.11.2012