使用map和$for函数应用减少Haskell eta

使用map和$for函数应用减少Haskell eta,haskell,Haskell,嗨,我的任务是编写一个函数,该函数从Int->Int和单个Int中获取函数列表,并检查应用于该Int的任何函数是否给出大于5的结果 这是我的解决方案: foo :: [Int -> Int] -> Int -> Bool foo ls = any (>5) . f ls where f ls v = map ($ v) ls 我想知道是否有一种方法可以在单行中(不使用where或let)使用eta减少最后一个参数(现在它是eta减少了,但它不是单行)。我试过这

嗨,我的任务是编写一个函数,该函数从
Int->Int
和单个
Int
中获取函数列表,并检查应用于该
Int
的任何函数是否给出大于5的结果

这是我的解决方案:

foo :: [Int -> Int] -> Int -> Bool
foo ls = any (>5) . f ls
     where f ls v = map ($ v) ls
我想知道是否有一种方法可以在单行中(不使用where或let)使用eta减少最后一个参数(现在它是eta减少了,但它不是单行)。我试过这样的方法:

foo ls = any (>5) . flip map ls
但是现在的问题是函数的调用,看起来像这样,这样它才能工作

foo [(+3), (*4), (+1)] ($2)
最后一个论点我不想写美元。我试过类似的方法(和此类似):


但我总是会犯一些错误。请注意,我不能更改类型签名,因此翻转。

由于您手头有一个应用程序列表,您只需使用应用程序操作符
将其应用为
[(+3),(*4),(+1)][2]
即可获得结果列表,如
[5,8,3]
。现在方便使用的是
any::Foldable t=>(a->Bool)->ta->Bool
函数。总而言之

checker x = any (>5) $ [(+3), (*4), (+1)] <*> [x]
checker x=任何(>5)$[(+3),(*4),(+1)][x]
我应该做这项工作。如果您需要无点版本,它会是什么样子

checker = any (>5) . ([(+3), (*4), (+1)] <*>) . pure
checker=any(>5)。([(+3), (*4), (+1)] ) . 纯净的

由于您手头有一个应用程序列表,您只需使用应用运算符
作为
[(+3),(*4),(+1)][2]
应用它,即可获得结果列表,如
[5,8,3]
。现在方便使用的是
any::Foldable t=>(a->Bool)->ta->Bool
函数。总而言之

checker x = any (>5) $ [(+3), (*4), (+1)] <*> [x]
checker x=任何(>5)$[(+3),(*4),(+1)][x]
我应该做这项工作。如果您需要无点版本,它会是什么样子

checker = any (>5) . ([(+3), (*4), (+1)] <*>) . pure
checker=any(>5)。([(+3), (*4), (+1)] ) . 纯净的

从完全非简化定义开始:

foo ls v = any (>5) (map (\f -> f v) ls)
我们可以使用lambdabot获得完全降低eta的解决方案:

foo = (any (> 5) .) . flip (map . flip id)

但是,这看起来很糟糕,不建议这样做。

从完全非简化定义开始:

foo ls v = any (>5) (map (\f -> f v) ls)
我们可以使用lambdabot获得完全降低eta的解决方案:

foo = (any (> 5) .) . flip (map . flip id)

然而,这看起来很糟糕,不应该建议这样做。

有办法吗?当然它可读吗?不,Haskell的设计让你远离了一些常见的错误,比如不必要的可变性或者隐藏使用(必要的)可变性状态。但是,遵循其他错误的道路会让人兴奋,比如以一种对可读性和可维护性有害的方式释放代码点

关于无点定义,转换为它们是一个完全机械的过程(只要起始定义中不涉及模式匹配)。有一些工具可以自动完成

首先编写完全扩展的定义:

foo ls x = any (>5) (map ($ x) ls)
然后将其放入您最喜欢的转换工具中。是一个在线服务,可以做到这一点

它吐出了完全不可读的东西:

foo = (any (> 5) .) . flip (map . flip id)
不要用那个。这不值得

但也许你只想放弃一个论点,这太过分了?好吧,你可以通过欺骗一点,假装第一个参数是作用域中的值,而不是参数,然后抛出以下定义:

foo x = any (>5) (map ($ x) ls)
它返回
foo=any(>5)。翻转地图。翻转id
,然后将参数插入到:

foo ls = any (> 5) . flip map ls . flip id
由于缺少
()
操作符的部分,这稍微好一些。但它仍然有
flipid
,这是最简单的混淆


不要这样做。保持克制。编写易于阅读和修改的代码。

有办法吗?当然它可读吗?不,Haskell的设计让你远离了一些常见的错误,比如不必要的可变性或者隐藏使用(必要的)可变性状态。但是,遵循其他错误的道路会让人兴奋,比如以一种对可读性和可维护性有害的方式释放代码点

关于无点定义,转换为它们是一个完全机械的过程(只要起始定义中不涉及模式匹配)。有一些工具可以自动完成

首先编写完全扩展的定义:

foo ls x = any (>5) (map ($ x) ls)
然后将其放入您最喜欢的转换工具中。是一个在线服务,可以做到这一点

它吐出了完全不可读的东西:

foo = (any (> 5) .) . flip (map . flip id)
不要用那个。这不值得

但也许你只想放弃一个论点,这太过分了?好吧,你可以通过欺骗一点,假装第一个参数是作用域中的值,而不是参数,然后抛出以下定义:

foo x = any (>5) (map ($ x) ls)
它返回
foo=any(>5)。翻转地图。翻转id
,然后将参数插入到:

foo ls = any (> 5) . flip map ls . flip id
由于缺少
()
操作符的部分,这稍微好一些。但它仍然有
flipid
,这是最简单的混淆


不要这样做。保持克制。编写易于阅读和修改的代码。

事实上,这是你最后一次尝试这个问题

foo ls = any (>5) . flip map ls ($)
已经非常接近解决方案

唯一的问题是,
($)
的定义:

($)
的第一个参数是一个函数
(a->b)
,但在您的情况下,需要是一个值
a
,因此只需
翻转($)
交换
($)
参数的顺序,并将其放回:

foo ls = any (>5) . flip map ls . flip ($)

是您想要的功能。

实际上,您最后一次尝试这个问题

foo ls = any (>5) . flip map ls ($)
已经非常接近解决方案

唯一的问题是,
($)
的定义:

($)
的第一个参数是一个函数
(a->b)
,但在您的情况下,需要是一个值
a
,所以只需
翻转($)
就可以交换参数的顺序