小编Zhi*_*gor的帖子

f,g,h :: Kleisli((->)e)ab` <=>`f >>>(g &&& h)=(f >>> g)&&&(f >>> h)`?

编辑:p如果存在以下功能f,我们将调用纯箭头:p = arr f

我试图更好地了解Haskell中的Arrows,我想弄清楚何时

f >>> (g &&& h) = (f >>> g) &&& (f >>> h)其中fgh是箭头。

显然,通常情况并非如此。在此特定示例中,副作用在右侧重复:

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) &&& …

monads haskell arrows kleisli reader-monad

5
推荐指数
1
解决办法
154
查看次数

为什么静态箭头概括了箭头?

众所周知,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 IdentityKleisli MaybeArrow实例。因此,我看不出泛化是如何工作的。

Wikibooks上的Haskell/Understanding Arrows 教程中 …

haskell arrows category-theory applicative

5
推荐指数
0
解决办法
174
查看次数

&lt;**&gt; 是 &lt;*&gt; 的变体,参数颠倒了。“颠倒”是什么意思?

在运行GHC.Base的描述中<**>

<*>参数颠倒的变体。

众所周知,在这种情况下“反转”并不意味着“翻转”为:

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)

haskell terminology operators applicative

5
推荐指数
3
解决办法
150
查看次数

GHCi 中如何处理中断?

我正在试验 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。这确实是一个错误,还是我错了?

haskell lazy-evaluation ghci

5
推荐指数
1
解决办法
72
查看次数

是否可以为 Arrows 而不是 ArrowApply 写下连接?

我试着写下来joinArr :: ??? a => a r (a r b) -> a r b。我想出了一个使用 的解决方案app,因此将范围缩小aArrowApply'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 …

monads haskell arrows category-theory

4
推荐指数
1
解决办法
185
查看次数

为什么在 Haskell 中为 Curry 类考虑局部小笛卡尔封闭类别是公平的?

Control.Category.Constrained是一个非常有趣的项目,它展示了笛卡尔封闭类别的类 - Curry.

然而,我不明白为什么我们会想到所有允许curryuncurryHom(X * Y, Z) ? Hom(X, Z^Y)就范畴论而言)的笛卡尔封闭范畴。维基百科说这种性质只适用于局部小的笛卡尔封闭类别。在这个帖子下,很多人建议Hask本身并不小(另一方面,每个人都说Hask不是笛卡尔封闭类别,我认为这是一种纯粹且无趣的形式主义)。

Math.SE上的这篇文章中,假设所有类别都在本地较小。但它是从我们讨论属性的数学角度给出的。我想知道为什么我们决定专注于和as的方法。是不是因为几乎每个了解 Haskell 的人也都知道这些函数?还是有其他原因?curryuncurryCurry

haskell currying typeclass category-theory

4
推荐指数
1
解决办法
121
查看次数

为什么 ArrowApply 是证明与 Monads 等效的唯一选择?

这个问题下leftarounabout留下了一个非常清楚的解释,为什么我们实际上考虑ArrowApplyMonad等价。

这个想法是在往返期间不丢失任何信息:

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 …

monads haskell arrows category-theory

3
推荐指数
1
解决办法
92
查看次数

Haskell:将整数推送到堆栈实现时的无限列表

我正在尝试实现一个简单的堆栈,但我很困惑为什么当我将一个整数推送到堆栈时会得到一个无限列表。

所有其他功能都按我的预期工作,但我不明白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)

stack haskell

3
推荐指数
1
解决办法
167
查看次数

Void 是初始元素还是零元素?

ZeroObjectControl.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)

但另一方面,术语零对象用于同时为initialterminal 的对象。说实话,我看不出Void终端。与absurd …

haskell types category-theory

1
推荐指数
1
解决办法
123
查看次数

Haskell 中的“模式匹配”类型

我想要一个函数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 中是否有类型(或类似机制)的模式匹配?

haskell types functional-programming

1
推荐指数
2
解决办法
115
查看次数

为什么不是扩展 Functor Contravariant 的 Phantom 类?

我在玩弄Data.Functor.Contravariant. 该phantom方法引起了我的注意:

phantom :: (Functor f, Contravariant f) => f a -> f b
phantom x = () <$ x $< ()
Run Code Online (Sandbox Code Playgroud)

或者,更具体地说,对它的注释:

如果f两者都是FunctorContravariant那么当您考虑每个类别的法律时,它实际上无法以任何有意义的能力使用它的论点。这种方法非常有用。当这两种情况存在,是合法的,我们有以下规律:fmap f ? phantomcontramap f ? phantom

既然fmap f ? contramap f ? phantom,为什么我们需要ContravariantFunctor实例?用另一种方式做这件事不是更方便:为一个类创建一个实例Phantom,它引入了phantom方法,然后自动Functor派生实例Contravariant?

class Phantom f where
    phantom :: f a -> f b …
Run Code Online (Sandbox Code Playgroud)

haskell covariance contravariance functor library-design

1
推荐指数
1
解决办法
118
查看次数