可变参数组合函数?

14

我正在尝试编写一个可变参数函数组合函数。它基本上相当于 (.),只是第二个参数函数是可变参数的。这应该允许像下面这样的表达式:

map even . zipWith (+)
或者只是
map even . zipWith

目前我所达到的效果需要添加 IncoherentInstances,并且需要一个非多态实例作为第一个参数函数。

{-# LANGUAGE FlexibleInstances, OverlappingInstances, MultiParamTypeClasses, 
FunctionalDependencies, UndecidableInstances, KindSignatures #-}

class Comp a b c d | c -> d where
    comp :: (a -> b) -> c -> d

instance Comp a b (a :: *) (b :: *) where
    comp f g = f g

instance Comp c d b e => Comp c d (a -> b) (a -> e) where
    comp f g = comp f . g

有什么想法吗?这种情况是否可能?


2
你能再解释一下“可变参数函数复合”是什么意思吗?可以加一些例子吗? - max taldykin
我在最后一次编辑中进行了一些澄清。除此之外,这两个示例有什么问题吗? - is7s
哦,抱歉。例子很好,但我没有意识到它们无法进行类型检查。 - max taldykin
1
你可能想看一下 Concatenative, Row-Polymorphic Programming in HaskellPlaying with Factor's Row Polymorphism in Haskell,因为行多态性特别适用于组合各种参数的函数。 - rampion
7
对于任何包含“可变参数”的内容,都不太可能与语言的其他部分兼容。虽然可以通过类型类技巧实现,而且很有趣,但我不建议在“实际代码”中使用。@is7s - luqui
显示剩余2条评论
1个回答

10

可以通过类型转换的方式使其与多态函数一起使用:

{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses,
  IncoherentInstances, UndecidableInstances,
  FunctionalDependencies, TypeFamilies,
  NoMonomorphismRestriction #-}


class Comp a b c | a b -> c where
    (...) :: a -> b -> c

instance (a ~ c, r ~ b) => Comp (a -> b) c r where
    f ... g = f g

instance (Comp (a -> b) d r1, r ~ (c -> r1)) => Comp (a -> b) (c -> d) r where
    f ... g = \c -> f ... g c

t1 = map even ... zipWith (+)
t2 = map even ... zipWith
t3 = (+1) ... foldr

但我怀疑你无法避免IncoherentInstances


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接