标签: semigroup

在追加下保持 IO 懒惰

我可能一直错误地认为 Haskell 比现在更懒惰,但我想知道是否有办法两全其美……

Data.MonoidData.Semigroup定义 的两个变体First。幺半群版本对最左边的非空值建模,而半群版本只是对最左边的值建模。

这适用于纯值,但考虑不纯值:

x = putStrLn "x" >> return 42
y = putStrLn "y" >> return 1337
Run Code Online (Sandbox Code Playgroud)

这两个值都具有类型Num a => IO aIO a是一个Semigroup实例,当a是:

instance Semigroup a => Semigroup (IO a)
  -- Defined in `Data.Orphans'
Run Code Online (Sandbox Code Playgroud)

这意味着可以组合两个IO (First a)值:

Prelude Data.Semigroup Data.Orphans> fmap First x <> fmap First y
x
y
First {getFirst = 42}
Run Code Online (Sandbox Code Playgroud)

我们可以看到,虽然双方xy产生各自的副作用,即使y是从来没有要求。

这同样适用于Data.Monoid …

haskell lazy-evaluation monoids semigroup

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

为什么Scalaz中的A => M [A]没有> =>半群?

这是我上一个问题的后续内容

Kleisli定义了两个运算符<=<(compose)和>=>(andThen).在>=>找我很自然的,我不明白怎么<=<会很有用.

而且,看起来没有>=>半群,A => M[A]但是<=<半群确实存在.

它背后的理由是什么?

scala scalaz kleisli semigroup

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

半组类型类(任意),组合稍有改变

使用cats.Semigroup可以这样写:

import cats.Semigroup
import cats.implicits._

val l1: String Either Int = Left("error")
val r1: String Either Int = Right(1)
val r2: String Either Int = Right(2)

l1 |+| r1 // Left("error")
r1 |+| r2 // Right(3)
Run Code Online (Sandbox Code Playgroud)

我希望有一个同样惯用的运算符(类似combine),其工作方式如下:

  • 如果Right我的计算中至少有一个,则返回一个Right
  • 如果只有 Left,则返回一个Left

例如:

Right(1) |+| Right(2) // Right(3) 
Right(1) |+| Left("2") // Right(1) 
Left("1") |+| Left("2") // Left("12") // in my particular case the wrapped value here does not really matter (could also be …
Run Code Online (Sandbox Code Playgroud)

functional-programming scala semigroup scala-cats

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

是否有一个模拟“补丁”的类?

我正在 Haskell 库中寻找如下所示的类(或者至少知道此类事物的数学名称):

class Monoid patch => MyThing patch t where
  applyPatch :: t -> patch -> t
Run Code Online (Sandbox Code Playgroud)

我可以有这样的实例:

instance MyThing (Last t) t where
  applyPatch x patch = case getLast patch of
    Just y => y
    Nothing => x
Run Code Online (Sandbox Code Playgroud)

但我也可以有这样的实例:

instance MyThing (Dual (Map key value)) (Map key value) where
  applyPatch x patch = ...
Run Code Online (Sandbox Code Playgroud)

补丁本质上是添加和/或替换映射中的键/值对。

如果你想删除,可以更进一步:

instance MyThing (Dual (Map key (Maybe value))) (Map key value) where
  applyPatch x patch = ...
Run Code Online (Sandbox Code Playgroud)

除了patch成为幺半群之外,我希望此类遵循的主要法则是结合性,具体来说:

forall (x :: …
Run Code Online (Sandbox Code Playgroud)

haskell discrete-mathematics monoids semigroup

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

在Haskell中导入时隐藏类型类实例声明

我正在尝试制作一个井字游戏,我决定构建单元格(板的元素)和板的类型如下:

data Cell  = X | O deriving (Show, Eq)
type Board = [[Maybe Cell]]
Run Code Online (Sandbox Code Playgroud)

这里,Nothing表示空单元格(Just X)和(Just O)分别表示用X和O填充的单元格.

我想将(Maybe Cell)定义为monoid,如下所示:

instance Monoid (Maybe Cell) where
  mempty             = Nothing
  mappend Nothing x  = x
  mappend (Just x) _ = (Just x)
Run Code Online (Sandbox Code Playgroud)

和董事会作为另一个幺半群

instance Monoid Board where
  mempty = [[Nothing, Nothing, Nothing]
           ,[Nothing, Nothing, Nothing]
           ,[Nothing, Nothing, Nothing]]
  mappend = zipWith (zipWith mappend) 
  -- where the right-hand-side mappend is the addition on (Maybe Cell)
Run Code Online (Sandbox Code Playgroud)

我知道我可以在没有幺半群的情况下完全实现这一点,但我正在尝试探索这个领域,而这只是一种非常巧妙的方式来编写它.

我得到的问题是Maybemonoid实例已经定义GHC.Base如下:

instance Semigroup …
Run Code Online (Sandbox Code Playgroud)

haskell typeclass monoids semigroup

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

如何解决 Haskell 代码错误“&lt;&gt;' 不是类 `Monoid' 的(可见)方法”?

让我们看看 Haskell 中用于处理反向列表的新数据类型的声明:

import Data.Monoid 
data RevList a = Nil | RCons (RevList a) a deriving (Eq, Show)

instance Monoid a => Monoid (RevList a) where
    mempty = Nil

instance Semigroup a => Monoid (RevList a) where
    Nil <> RCons (RevList a) a = RCons (RevList a) a
    RCons (RevList a) a <> RNil = RCons (RevList a) a
    Nil <> Nil = Nil
Run Code Online (Sandbox Code Playgroud)

我困扰的问题是编译失败,其描述如下:

 `<>' is not a (visible) method of class `Monoid'
Run Code Online (Sandbox Code Playgroud)

首先,我尝试在没有任何 Semigroup 实例声明的情况下创建一个 Monoid 实例,但是在阅读此问题 …

haskell monoids semigroup

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

Haskell,实现 Monoids。什么是 Semigroup?为什么它表现得如此奇怪?

我想实现一个名为 ComplexNumber 的自定义数据类型,如下所示: data ComplexNumber a = C (a,a)

现在我想实现 Monoid 变量并定义二进制 mempty 元素和 mappend,如下所示:

instance Num a => Monoid (ComplexNumber a) where
    mempty = C (0,0)
    mappend = (C (a1, b1)) (C (a2, b2)) = C (a1 + a2, b1 + b2)
Run Code Online (Sandbox Code Playgroud)

但这没有成功,所以试图找出原因并遇到了 Semigroup (我仍然不太理解)并找到了一个至少可以编译并且似乎可以使用的解决方案:

instance Num a => Semigroup (ComplexNumber a) where
    (C (a1, b1)) <> (C (a2,b2)) = C (a1 + a2, b1 + b2)

instance Num a => Monoid (ComplexNumber a) where
    mempty = C (0,0) …
Run Code Online (Sandbox Code Playgroud)

haskell monoids semigroup

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

具有不同定义的mempty取决于mempty是左还是右arg?

我有以下数据类型和半群实例:

data Or a b =
  Fst a
  | Snd b deriving (Eq, Show)

instance Semigroup (Or a b) where
  (<>) (Fst a) (Fst b) = Fst b
  (<>) (Snd a) (Fst b) = Snd a
  (<>) (Fst a) (Snd b) = Snd b
  (<>) (Snd a) (Snd b) = Snd a
Run Code Online (Sandbox Code Playgroud)

我想为上面的类型创建一个monoid实例,但我不知道如何做到这一点.如果我使用以下定义

instance (Monoid a, Monoid b) => Monoid (Or a b) where
  mempty = (Fst mempty)
  mappend = (<>)
Run Code Online (Sandbox Code Playgroud)

<>除了I之外,它将适用于所有输入对mappend

(Fst a) <> mempty
Run Code Online (Sandbox Code Playgroud)

将评估为mempty …

haskell monoids semigroup

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