编辑:p如果存在以下功能f,我们将调用纯箭头:p = arr f。
我试图更好地了解Haskell中的Arrows,我想弄清楚何时
f >>> (g &&& h) = (f >>> g) &&& (f >>> h)其中f,g,h是箭头。
显然,通常情况并非如此。在此特定示例中,副作用在右侧重复:
GHCi> c = Kleisli $ \x -> ("AB", x + 1)
GHCi> fst . runKleisli (c >>> c &&& c) $ 1
"ABABAB"
GHCi> fst . runKleisli ((c >>> c) &&& (c >>> c)) $ 1
"ABABABAB"
Run Code Online (Sandbox Code Playgroud)
显然,f >>> (g &&& h) = (f >>> g) &&& …
众所周知,Applicative概括Arrows。在习语是健忘,箭都一丝不苟,单子是混杂由Sam林德利,菲利普·沃德勒和Jeremy Yallop纸据说Applicative是相当于静态箭头,这是其下述同构持有箭头:
arr a b :<->: arr () (a -> b)
据我所知,它可以通过以下方式说明:
注:newtype Identity a = Id { runId :: a }。
Klesli Identity是一个静态箭头,因为它包裹k :: a -> Identity b。同构只是删除或添加包装器。
Kleilsi Maybe不是k = Kleisli (const Nothing)存在的静态箭头- 所有f :: a -> bs 都对应于Just . f,并且k在同构中没有位置。
但在同一时间都Kleisli Identity和Kleisli Maybe是Arrow实例。因此,我看不出泛化是如何工作的。
<*>参数颠倒的变体。
众所周知,在这种情况下“反转”并不意味着“翻转”为:
GHCi> [1, 2, 3] <**> [(^2), (+1)]
[1,2,4,3,9,4]
GHCi> [(^2), (+1)] <*> [1, 2, 3]
[1,4,9,2,3,4]
Run Code Online (Sandbox Code Playgroud)
那么,“反转”是什么意思呢?
旁注:有具有(<**>) = flip (<*>). 例如,这是我给读者的证明 ( (->) e):
(->) e: f <**> g =
= liftA2 (flip ($)) f g =
= (flip ($) <$> f) <*> g =
= \e -> ((flip ($) . f) e) (g e) =
= \e -> flip ($) (f e) $ (g e) =
= …Run Code Online (Sandbox Code Playgroud) 我正在试验 GHCi 的:sprint命令。考虑以下:
GHCi> xs = [1..10] :: [Int]
GHCi> :sprint xs
xs = _
GHCi> length xs
10
GHCi> :sprint xs
xs = [1,2,3,4,5,6,7,8,9,10]
Run Code Online (Sandbox Code Playgroud)
这按预期工作。我感兴趣的是:sprint我们中断一些计算后的行为。考虑以下:
GHCi> xs = [1..] :: [Int]
GHCi> :sprint xs
xs = _
GHCi> length xs
Interrupted.
GHCi> :sprint xs
Run Code Online (Sandbox Code Playgroud)
它挂了。
预期的结果是这样的(以:s的数量为模):
xs = _ : _ : _ : _
Run Code Online (Sandbox Code Playgroud)
什么原因导致:sprint ...冻结?为什么无法访问有关已计算的列表部分的信息?对我来说这似乎是一个错误 - 没有真正的理由抛弃被打断的所有工作length。这确实是一个错误,还是我错了?
我试着写下来joinArr :: ??? a => a r (a r b) -> a r b。我想出了一个使用 的解决方案app,因此将范围缩小a到ArrowApply's:
joinArr :: ArrowApply a => a r (a r b) -> a r b
joinArr g = g &&& Control.Category.id >>> app
Run Code Online (Sandbox Code Playgroud)
是否可以为箭头写下此功能?
我的猜测是否定的。
Control.Monad.join可能>>=是Monad类型类定义中的一个很好的替代品:m >>= k = join $ k <$> m.
有了joinArr :: Arrow a => a r (a r b) (a r b)我们的手,就可以写下instance Arrow …
Control.Category.Constrained是一个非常有趣的项目,它展示了笛卡尔封闭类别的类 - Curry.
然而,我不明白为什么我们会想到所有允许curry和uncurry(Hom(X * Y, Z) ? Hom(X, Z^Y)就范畴论而言)的笛卡尔封闭范畴。维基百科说这种性质只适用于局部小的笛卡尔封闭类别。在这个帖子下,很多人建议Hask本身并不小(另一方面,每个人都说Hask不是笛卡尔封闭类别,我认为这是一种纯粹且无趣的形式主义)。
在Math.SE上的这篇文章中,假设所有类别都在本地较小。但它是从我们讨论属性的数学角度给出的。我想知道为什么我们决定专注于和as的方法。是不是因为几乎每个了解 Haskell 的人也都知道这些函数?还是有其他原因?curryuncurryCurry
在这个问题下,leftarounabout留下了一个非常清楚的解释,为什么我们实际上考虑ArrowApply和Monad等价。
这个想法是在往返期间不丢失任何信息:
arrAsFunction :: Arrow k => k x y -> (x -> k () y)
arrAsFunction ? x = ? <<< arr (const x)
retrieveArrowFromFunction :: ? k x y .
ArrowApply k => (x -> k () y) -> k x y
retrieveArrowFromFunction f = arr f' >>> app
where f' :: x -> (k () y, ())
f' x = (f x, ())
Run Code Online (Sandbox Code Playgroud)
我(可能)明白,为什么我们开始谈论(x …
我正在尝试实现一个简单的堆栈,但我很困惑为什么当我将一个整数推送到堆栈时会得到一个无限列表。
所有其他功能都按我的预期工作,但我不明白push. 当我尝试为自己分配一个空堆栈时出错,该堆栈已推送如下变量:
? > a = makeStack
? > push 3 a
[3]
? > a
[]
? > a = push 3 a
? > a
[3,3,3,3,3,3,3,3,3,3^CInterrupted.
Run Code Online (Sandbox Code Playgroud)
type Stack a = [a]
makeStack :: Stack a
makeStack = []
push :: a -> Stack a -> Stack a
push a as = (a:as)
Run Code Online (Sandbox Code Playgroud) ZeroObject的Control.Category.Constrained默认Void。很明显,这Void是一个初始对象:
{-# LANGUAGE EmptyCase #-}
absurd :: Void -> a
absurd x = case x of
Run Code Online (Sandbox Code Playgroud)
但是为什么叫它ZeroObject呢?一方面,由于UnitObject默认为()并且我们与算术非常匹配:
((), x) ? x ? (x, ()); 1 * x = x = x * 1.
Void + x ? x ? x + Void; 0 + x = x = x + 0.
Run Code Online (Sandbox Code Playgroud)
但另一方面,术语零对象用于同时为initial和terminal 的对象。说实话,我看不出Void是终端。与absurd …
我想要一个函数f作为Ints的增量和所有其他类型的标识。我尝试启用TypeApplications扩展并以最直接的方式执行此操作:
f :: forall a. a -> a
f @Int x = x + 1
f @_ x = x
Run Code Online (Sandbox Code Playgroud)
但是扩展并没有启用这样的模式:
<interactive>:6:1: error: Parse error in pattern: f @Int
Run Code Online (Sandbox Code Playgroud)
Haskell 中是否有类型(或类似机制)的模式匹配?
我在玩弄Data.Functor.Contravariant. 该phantom方法引起了我的注意:
phantom :: (Functor f, Contravariant f) => f a -> f b
phantom x = () <$ x $< ()
Run Code Online (Sandbox Code Playgroud)
或者,更具体地说,对它的注释:
如果
f两者都是Functor,Contravariant那么当您考虑每个类别的法律时,它实际上无法以任何有意义的能力使用它的论点。这种方法非常有用。当这两种情况存在,是合法的,我们有以下规律:fmap f ? phantom,contramap f ? phantom
既然fmap f ? contramap f ? phantom,为什么我们需要Contravariant和Functor实例?用另一种方式做这件事不是更方便:为一个类创建一个实例Phantom,它引入了phantom方法,然后自动为?Functor和派生实例Contravariant
class Phantom f where
phantom :: f a -> f b …Run Code Online (Sandbox Code Playgroud) haskell ×11
arrows ×4
monads ×3
applicative ×2
types ×2
covariance ×1
currying ×1
functor ×1
ghci ×1
kleisli ×1
operators ×1
reader-monad ×1
stack ×1
terminology ×1
typeclass ×1