我正在寻找一些非常简单,易于掌握的递归方案和核心运动方案(catamorphisms,anorporphisms,hylomorphisms等)的解释,这些解释不需要跟随大量的链接,或者打开类别理论教科书.我确信我已经无意识地重新设计了许多这些方案,并在编码过程中将它们"应用"在我的头脑中(我相信我们很多人都有),但我不知道(共同)递归方案我是什么使用被称为.(好吧,我撒了谎.我刚刚读了一些这些,这引发了这个问题.但在今天之前,我一无所知.)
我认为这些概念在编程社区中的传播受到了令人生畏的解释和例子的阻碍 - 例如在维基百科上,而且在其他地方.
它们的名字也可能受到阻碍.我认为有一些替代的,较少的数学名称(关于香蕉和带刺铁丝网的东西?)但是我不知道我使用的递归方案的名称是什么.
我认为使用表示简单实际问题的数据类型的示例,而不是抽象数据类型(如二叉树)会有所帮助.
是否有一个列表,其中包含没有广泛的类别理论知识的人可以访问的示例?
我发明了一种递归方案,这种方法是对同态性的推广.折叠具有catamorphism的数据结构时,您无法访问子项,只能访问折叠的子结果:
{-# LANGUAGE DeriveFunctor #-}
import qualified Data.Map as M
newtype Fix f = Fix { unFix :: f (Fix f) }
cata :: Functor f => (f b -> b) -> Fix f -> b
cata phi = self where
self = phi . fmap (\x -> self x) . unFix
Run Code Online (Sandbox Code Playgroud)
折叠功能phi只能访问self x原始结果,但不能访问原始结果x.所以我添加了一个加入功能:
cataWithSubterm :: Functor f => (Fix f -> c -> b) -> (f b -> c) -> Fix f -> …Run Code Online (Sandbox Code Playgroud) 除了最后一个列表元素外,如何最好地映射列表的所有元素?
假设我们有一个列表let l = [1,2,3,4]并希望得到[2,3,4,4].
我确实有一个解决方案,但它感觉不像是"功能"的方式(在ghci中):
let l = [1,2,3,4]
let len = toIntegral $ length l -- to avoid a type mismatch Integer <-> Int
let l1 = zip l [1..]
let l2 = map (\(x,y) -> if y < len then (x + 1,y) else (x,y)) l1
let l3 = map (fst) l2
Run Code Online (Sandbox Code Playgroud)
不太好......我希望有更好的方法!由于我是函数式编程的新手,我不知道从哪里开始寻找它.
因此,有一种被称为"折叠的普遍属性"的东西,完全如下:
g [] = i; g (x:xs) = f x (g xs) <=> g = fold f i
但是,正如您现在可能的那样,有一些罕见的情况dropWhile,fold f i 除非您将其概括,否则无法重新定义.
最简单但最明显的推广方法是重新定义通用属性:
g' y [] = j y; g' y (x:xs) = h y x xs (g' y xs) <=> g' y = fold (?) l
在这一点上,我可以做出我的假设:我假设存在某种功能p :: a -> b -> b,这将满足等式g' y = fold p l.让我们尝试用普遍属性帮助解决给定的方程式,一开始就提到:
g' y [] = j y = fold p l [] = l …haskell functional-programming proof generic-programming fold
我需要一个执行此操作的函数:
>>> func (+1) [1,2,3]
[[2,2,3],[2,3,3],[2,3,4]]
Run Code Online (Sandbox Code Playgroud)
我的实际案例更复杂,但这个例子显示了问题的要点.主要的区别在于,实际上使用索引是不可行的.本List应该是一个Traversable或Foldable.
编辑:这应该是功能的签名:
func :: Traversable t => (a -> a) -> t a -> [t a]
Run Code Online (Sandbox Code Playgroud)
更接近我真正想要的是相同的签名,traverse但无法弄清楚我必须使用的功能,以获得所需的结果.
func :: (Traversable t, Applicative f) :: (a -> f a) -> t a -> f (t a)
Run Code Online (Sandbox Code Playgroud) 对Praxis编程的这一提交给出了一个O(n)函数,它"撤消"二进制搜索树的前序遍历,将列表转换回树.提供缺失的数据声明:
data Tree a = Leaf | Branch {value::a, left::Tree a, right:: Tree a}
deriving (Eq, Show)
fromPreOrder :: Ord a => [a] -> Tree a
fromPreOrder [] = Leaf
fromPreOrder (a:as) = Branch a l (fromPreOrder bs)
where
(l,bs) = lessThan a as
lessThan n [] = (Leaf,[])
lessThan n all@(a:as)
| a >= n = (Leaf,all)
| otherwise = (Branch a l r,cs)
where (l,bs) = lessThan a as
(r,cs) = lessThan n bs
很明显,在每个递归步骤中将一个构造函数添加到树中,这是其效率的关键.
唯一的"问题"是列表是手动穿过计算的,这不是一种非常糟糕的Haskellian方式,并且使得它更难以看到它实际上是以单线程方式逐个元素地消耗.
我尝试使用状态monad(在 …
有没有办法找出列表的本地最大值使用foldr或者foldl可能我必须使用unfoldr因为列表的第一个和最后一个元素不是本地最大值?
我理解如何使用带有警卫的递归来找到它,例如
localMax :: [Int] -> [Int]
localMax [] = []
localMax (x:[]) = []
localMax (x:y:[]) = []
localMax (x:y:z:zs)
| y > z && y > x = y:localMax (y:z:zs)
| otherwise = localMax (y:z:zs)
Run Code Online (Sandbox Code Playgroud) lambda演算的n元组通常定义为:
1-tuple: ? a t . t a
1-tuple-fst: ? t . t (? a . a)
2-tuple: ? a b t . t a b
2-tuple-fst: ? t . t (? a b . a)
2-tuple-snd: ? t . t (? a b . b)
3-tuple: ? a b c t . t a b c
3-tuple-fst: ? t . t (? a b c . a)
3-tuple-snd: ? t . t (? a b c . b)
3-tuple-trd: …Run Code Online (Sandbox Code Playgroud) 说我有这样的列表:
[4,5,6,7,1,2,3,4,5,6,1,2]
Run Code Online (Sandbox Code Playgroud)
我需要一个Haskell函数,它将此列表转换为列表列表,列表由原始列表的段组成,这些段按升序排列.所以结果应该是这样的:
[[4,5,6,7],[1,2,3,4,5,6],[1,2]]
Run Code Online (Sandbox Code Playgroud)
有什么建议?
我正在寻找类型的功能
[[(a, b)]] -> [(a, [b])]
并且Hoogle告诉我没有一个,所以我写了这个:
transpose :: (Eq a) => [[(a, b)]] -> [(a, [b])]
transpose alists = uncurry zip $ foldl combine ([], []) alists
where combine memo new = foldl tally memo new
tally ([], []) (k, v) = ([k], [[v]])
tally ((ksHead:ksRest), (vsHead:vsRest)) (k, v) =
if k == ksHead
then (ksHead:ksRest, (v:vsHead):vsRest)
else (ksHead:ks, vsHead:vs)
where (ks, vs) = tally (ksRest, vsRest) (k, v)
Run Code Online (Sandbox Code Playgroud)
按重要性排序:
transpose这个东西是正确的名字吗?编辑
因为有人对这种味道感兴趣:
我正在写一个堆栈排名应用程序,来自用户的选票以形式出现 …
haskell ×11
list ×3
recursion ×2
catamorphism ×1
combinators ×1
fold ×1
lambda ×1
map-function ×1
partition ×1
proof ×1
traversable ×1
tree ×1
tuples ×1