gpt4 book ai didi

haskell - 如何编写半群实例?

转载 作者:行者123 更新时间:2023-12-02 21:33:00 27 4
gpt4 key购买 nike

问题

给定一个数据类型,实现 Semigroup 实例。这是我要实现的数据类型: data Or a b = Fst a | Snd b deriving (Eq, Show, Num) 。它的功能应该像这样:

Prelude> Fst 1 <> Snd 2
Snd 2
Prelude> Fst 1 <> Fst 2
Fst 2
Prelude> Snd 1 <> Fst 2
Snd 1
Prelude> Snd 1 <> Snd 2
Snd 1

当我测试像 > Fst "help" <> Fst "me" 这样的值时它工作正常,但是当我测试其他值时,我收到错误。当我尝试通过从错误中派生类来修复这些错误时,我收到了更多错误。我在这里做错了什么?

我的代码

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

instance (Semigroup a, Semigroup b, Num a, Num b) => Semigroup (Or a b) where
(Snd a) <> _ = Snd a
_ <> (Snd a) = Snd a
(Fst a) <> (Fst b) = Fst b

错误

当我尝试使用整数进行测试时 > Fst 1 <> Fst 2我得到:

No instance for (Num a0) arising from a use of ‘it’
The type variable ‘a0’ is ambiguous
Note: there are several potential instances:
instance RealFloat a => Num (Data.Complex.Complex a)
-- Defined in ‘Data.Complex’
instance Data.Fixed.HasResolution a => Num (Data.Fixed.Fixed a)
-- Defined in ‘Data.Fixed’
instance forall (k :: BOX) (f :: k -> *) (a :: k).
Num (f a) =>
Num (Data.Monoid.Alt f a)
-- Defined in ‘Data.Monoid’
...plus 21 others
In the first argument of ‘print’, namely ‘it’
In a stmt of an interactive GHCi command: print it

当我尝试派生 Num 类 data Or a b = Fst a | Snd b deriving (Eq, Show, Num) 时我得到:

    Can't make a derived instance of ‘Num (Or a b)’:
‘Num’ is not a derivable class

In the data declaration for ‘Or’
Failed, modules loaded: none.

最佳答案

真正的问题是您对实例施加的约束,而您并不需要这些约束。就这么写

instance Semigroup (Or a b) where
(Snd a) <> _ = Snd a
_ <> (Snd a) = Snd a
(Fst a) <> (Fst b) = Fst b

正如 chepner 所示,您实际上可以减少行数和模式数,并返回参数之一作为结果,而不是构造它的新副本。这可能有利于提高效率。

不太重要的是,模式中的括号都是多余的,因为应用程序的优先级高于任何运算符。

关于haskell - 如何编写半群实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39232294/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com