lens
offer holesOf
,这是这个假设函数的一个更通用和更强大的版本:
holesList :: Traversable t
=> t a -> [(a, a -> t a)]
Run Code Online (Sandbox Code Playgroud)
给定一个容器,holesList
生成一个容器元素列表以及替换这些元素的函数.
holesList
类似于真实的类型holesOf
,无法捕获生成的对数等于容器元素数的事实.因此,更美丽的类型将是
holes :: Traversable t
=> t a -> t (a, a -> t a)
Run Code Online (Sandbox Code Playgroud)
我们可以holes
通过使用holesList
制作一个列表然后遍历来State
重新填充元素来实现.但这有两个原因令人不满意,其中一个原因具有实际后果:
slurping代码将有一个无法访问的错误调用来处理在遍历完成之前列表为空的情况.这很恶心,但对使用该功能的人来说可能并不重要.
无限延伸到左侧或左下方的容器根本不起作用.向左延伸很远的容器处理效率非常低.
我想知道是否有任何办法解决这些问题.使用Magma
镜头之类的东西很有可能捕捉到遍历的形状:
data FT a r where
Pure :: r -> FT a r
Single :: a -> FT a a
Map :: (r -> s) -> FT a r -> FT …
Run Code Online (Sandbox Code Playgroud) 这个问题实际上是一个非常密切相关问题的小格子; 我认为将它分解为止并不是很有意义.
创建a的基本方法之一Vector
就是使用unsafeFreeze
.顾名思义,unsafeFreeze
真的是不安全的.特别是,没有什么能阻止MVector
传递的内容unsafeFreeze
在被冻结后被修改.这导致了两个不同的问题:
它可以使"不可变"向量的值发生变化.这只是Haskell一般避开的那种怪异动作.
修改冻结的矢量可以(至少可能)混淆垃圾收集器.没有文件证明垃圾收集器将扫描冻结的阵列以确保其内容被撤离.更一般地说,绝对禁止变异载体变异,这样做的结果完全没有说明.
所述vector
包[1]提供了两种高效,看似安全,用于创建不变矢量原语:create
和createT
:
create :: (forall s. ST s (MVector s a)) -> Vector a
createT :: Traversable t => (forall s. ST s (t (MVector s a))) -> t (Vector a)
Run Code Online (Sandbox Code Playgroud)
无视矢量融合业务,基本实现看起来像
create m = runST $ m >>= unsafeFreeze
createT m = runST $ m >>= traverse unsafeFreeze
Run Code Online (Sandbox Code Playgroud)
create
非常安全.它运行给定的ST s
动作,它必须创建一个新的MVector s
(runST
确保它不能使用现有的类型,并确保fixST …
我试图通过在Haskell中实现它来了解镜头.我已经实现了view
如下组合器:
{-# LANGUAGE RankNTypes #-}
import Control.Applicative
import Data.Traversable
type Lens s a = Functor f => (a -> f a) -> s -> f s
view :: Lens s a -> s -> a
view lens = getConst . lens Const
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试与它一起使用时,traverse
我收到以下错误消息:
Prelude> :load Lens.hs
[1 of 1] Compiling Main ( Lens.hs, interpreted )
Ok, modules loaded: Main.
*Main> :t view traverse
<interactive>:1:6:
Could not deduce (Applicative f) arising from a use of ‘traverse’
from …
Run Code Online (Sandbox Code Playgroud) 如果我有一个Traversable
实例,xs
我该如何将其转换为Vector
?
在Applicative
深入研究的同时,我来到了Traversable
.虽然我已经Foldable
从LYHGG知道了,但我还没有见过前者,所以我开始阅读关于Traversable的Haskell wiki.
在阅读它时,我理解为什么它Foldable.fold
是平行的Traversable.sequenceA
并且Foldable.foldMap
是平行的Traversable.traverse
.
我也看到每个Traversable
也是a Foldable
和a Functor
,sequenceA
并且traversal
彼此有默认实现:
traverse f = sequenceA . fmap f
sequenceA = traverse id
Run Code Online (Sandbox Code Playgroud)
所以,正如我在LYHGG中看到的那样,它foldMap
是一个最小的完整定义Foldable
,我认为,它是平行的traverse
,所以fold
(它是平行的sequenceA
)也是一个最小的完整定义(它不是)... Foldable
是不是Functor
喜欢Traversable
的,所以我们不能申请这个:
foldMap f = fold . fmap f
fold = foldMap id -- this is ok
Run Code Online (Sandbox Code Playgroud)
为什么不是每Foldable
一个 …
我正在尝试使用Tardis monad 在任何可遍历的容器上实现冒泡排序.
{-# LANGUAGE TupleSections #-}
module Main where
import Control.DeepSeq
import Control.Monad.Tardis
import Data.Bifunctor
import Data.Traversable
import Data.Tuple
import Debug.Trace
newtype Finished = Finished { isFinished :: Bool }
instance Monoid Finished where
mempty = Finished False
mappend (Finished a) (Finished b) = Finished (a || b)
-- | A single iteration of bubble sort over a list.
-- If the list is unmodified, return 'Finished' 'True', else 'False'
bubble :: Ord a => [a] -> (Finished, …
Run Code Online (Sandbox Code Playgroud) 三天后我有一个 Haskell 考试,所以我想我应该练习一下并提取过去的考试,其中一个具有以下 Tree 数据类型:
data Tree a = Leaf1 a | Leaf2 a a | Node (Tree a) (Maybe (Tree a)) deriving (Eq, Ord, Show)
Run Code Online (Sandbox Code Playgroud)
起初看起来并不那么具有挑战性,但后来我意识到我必须为这棵树编写一个 Traversable 实例。处理树叶很容易:
instance Traversable Tree where
traverse f (Leaf1 a) = Leaf1 <$> f a
traverse f (Leaf2 a b) = Leaf2 <$> f a <*> f b
Run Code Online (Sandbox Code Playgroud)
但是,我开始遇到 Node.js 的问题。
traverse f (Node t Nothing) = Node <$> traverse f t <*> Nothing
traverse f (Node l (Just r)) = Node <$> …
Run Code Online (Sandbox Code Playgroud) 最近我一直在“将一切提炼为基础”,并且我一直无法找到关于如何定义 Traversable 类型类的明确的理论原因,只有“能够遍历是有用的”的实际原因在应用余代数上,很多数据类型都可以做到这一点”以及很多提示。
我知道有一个适用的“家族”,如https://duplode.github.io/posts/divisible-and-the-monoidal-quartet.html所描述。
我还知道,虽然 Traversable 遍历是应用性余代数,但“semigroupoids”中的 Traversable1 类型类描述了应用性余代数,“distributive”中的 Distributive 类型类描述了函子代数。
此外,我知道 Foldable、Foldable1 和理论折叠家族成员描述了可以使用幺半群、半群和相应的幺半群家族成员(例如岩浆(用于折叠为二叉树)和每个的交换版本)折叠的数据类型(用于折叠为每个的无序版本)。
因此,由于 Traversable 是 Foldable 的子类,我假设它本质上是幺半群的,同样,我假设 Traversable1 本质上是半群的,而 Distributive 本质上是共单体的(如“分布”包中的描述中所述)。
这感觉像是正确的轨道,但是 Applicative 和 Apply 从哪里来呢?有岩浆版本和交换版本吗?在具有非平凡共类群的范畴中是否存在分布式族?
本质上,我的问题是“这些类型类是否存在,它们是什么?如果不存在,为什么不存在?”:
class FoldableMagma t => TraversableMagma t where
traverseMagma :: ??? f => (a -> f b) -> (t a -> f (t b))
class FoldableCommute t => TraversableCommute t where
traverseCommute :: ??? f => (a -> f b) -> (t a -> f (t b))
class Foldable t …
Run Code Online (Sandbox Code Playgroud) 如何检测变量是Traversable
在foreach
循环中使用的对象?
if(is_traversable($variable)) {
return (array) $variable;
}
Run Code Online (Sandbox Code Playgroud) class (Functor t, Foldable t) => Traversable t where
traverse :: Applicative f => (a -> f b) -> t a -> f (t b)
traverse g = sequenceA . fmap g
sequenceA :: Applicative f => t (f a) -> f (t a)
sequenceA = traverse id
Run Code Online (Sandbox Code Playgroud)
它如何Traversable
同时使用Foldable
和继承子类的事实Functor
?
t
如果是可遍历类型,t
则它也意味着函子类型和可折叠类型。
我看到的事实t
是一个仿函数类型,即fmap
,在使用traverse
。
是在t
某处使用的可折叠类型的事实吗?
是否traverse
使用t
可折叠类型的事实?
使用哪个事实sequenceA
:t
是仿函数类型,t …
traversable ×10
haskell ×9
arrays ×2
foldable ×2
functor ×2
vector ×2
applicative ×1
bubble-sort ×1
distributive ×1
haskell-lens ×1
lenses ×1
maybe ×1
monads ×1
php ×1
tree ×1