当前位置:  开发笔记 > 小程序 > 正文

折叠功能列表?

如何解决《折叠功能列表?》经验,为你挑选了1个好方法。



1> leftaroundab..:

好吧,正如你自己注意到它实际上是不可能的,因为不同的列表长度(对于类型系统是不可见的)会导致不同的类型.唯一"可靠"的方法就是使用某种编译时列表; 各种各样,但没有一个真正稳定支持和易于使用.

最简单的替代方法是将参数作为列表.即

ifxChain :: [a->a->a] -> [a] -> a

这个可以轻松实现:它基本上是一个zip,为每个函数提供第二个参数,省略第一个参数.然后通过结果的单参数函数列表折叠第一个参数:

ifxChain fs (p0:ps) = foldl' (flip ($)) p0 $ zipWith flip fs ps

您可能希望添加具有不匹配长度的列表的处理,应该是合理安全的.


如果你坚持实际可变数量的函数参数(我认为这不好!)那么你需要一些类型类hackery.这种可变函数最为人所知printf.

{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleInstances     #-}

class ChainedFunc f t where
  chainIfxs :: [t->t->t] -> t -> f
  chainIfxs fs i = chainIfxPre i id $ reverse fs
  chainIfxPre :: t -> (t->t) -> [t->t->t] -> f

instance ChainedFunc t t where
  chainIfxPre i f [] = f i

instance (ChainedFunc f t) => ChainedFunc (t->f) t where
  chainIfxPre i fin (f:fs) x0 = chainIfxPre i (flip f x0 . fin) fs

显然,这在很多方面都不好看.但是,嗯,它有效......啊......

Main> chainIfxs [(*),(+),( - )](2 :: Int)(3 :: Int)(4 :: Int)(5 :: Int):: Int
15

推荐阅读
路人甲
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有