【问题标题】:How can I use functors or applicatives to rewrite this Haskell function over lists of tuples如何使用函子或应用程序在元组列表上重写此 Haskell 函数
【发布时间】:2019-03-22 18:35:17
【问题描述】:

有没有更好的方法来使用函子或应用程序编写以下函数fs'

fncnB = (* 2)
fncnA = (* 3)
fs' fs = zip (map (fncnA . fst) fs) $ map (fncnB . snd) fs

我从this question 看到,我可以依靠列表的函子实例来映射单个函数,该函数作用于每个元组的两个元素,或者例如在元组的应用实例上将函数应用于双元组的后半部分,但我很好奇仿函数和应用程序如何适应对多组件数据类型列表进行操作的情况。

【问题讨论】:

  • 与 Functor 或 Applicative 无关,但您可以通过列表理解很好地重写它:fs' fs = [(fncnA x, fncnB y) | (x, y) <- fs]
  • 或者,使用Arrow 方法,只需fs' = map (fncnA &&& fncnB)。 (我想。我对 Arrows 并没有真正的经验。)
  • @RobinZigmond:正确的想法,错误的功能——你想要(***)(&&&) 将用于 ((* 2) &&& (* 3)) 5 == (10,15)
  • 谢谢@AntalSpector-Zabusky,我知道我会在某个地方搞混 :)

标签: haskell functor applicative


【解决方案1】:

元组是双函子,所以bimap 是可用的。

import Data.Bifunctor

fncnB = (* 2)
fncnA = (* 3)
fs' = map (bimap fncnA fncnB)

不需要第三方库。

【讨论】:

    【解决方案2】:

    您需要的是 mapPair 函数,它在 the utility-ht package 中定义,但它只是

    mapPair :: (a -> c, b -> d) -> (a,b) -> (c,d)
    mapPair (f,g) (a,b) = (f a, g b) 
    

    使用

    Prelude> mapPair ((* 2), (* 3)) (2,3)
    (4,9)
    

    Prelude> map (mapPair ((* 2), (* 3))) [(1,2),(2,3)]
    [(2,6),(4,9)]
    

    【讨论】:

    • mapPair 也等于uncurry bimap(其中bimap 来自Data.Bifunctor)。
    猜你喜欢
    • 1970-01-01
    • 2019-09-08
    • 1970-01-01
    • 2013-11-14
    • 1970-01-01
    • 1970-01-01
    • 2022-01-12
    • 1970-01-01
    • 2014-11-23
    相关资源
    最近更新 更多