我正在尝试实现一个通用的类似环形的东西,并将其应用于 Paul Hudak 在《哈斯克尔音乐学院》一书中描述的音乐数据结构。当然,有很多半群/幺半群的恶作剧被省略,但我有以下相关代码:
newtype Duo a b = Duo {duo1 :: a} -- A ring-like structure
data Song a =
Primitive a
| Song a :+: Song a -- Composing Music Sequentially
| Song a :=: Song a deriving Eq -- Composing Music Concurrently (in parallel)
instance Functor Song where
fmap f (x :+: y) = fmap f x :+: fmap f y
fmap f (x :=: y) = fmap f x :=: fmap f y
fmap f (Primitive x) = Primitive $ f x
newtype Concurrent a = Concurrent {fromConcurrent :: Song a} deriving (Show)
newtype Sequential a = Sequential {fromSequential :: Song a} deriving (Show)
type Music a = Duo (Maybe (Concurrent a)) (Maybe (Sequential a))
我正在尝试编写一个用于音乐的 Functor 实例,因为 Duo 没有 Functor,我认为这不会成为问题。
我写了以下实现:
instance Functor Music where
fmap :: (a -> b) -> Music a -> Music b
fmap f = Duo . fmap (fmap f . fromConcurrent) . duo1
但我收到以下错误:
• The type synonym ‘Music’ should have 1 argument, but has been given none • In the instance declaration for ‘Functor Music’ | 167 | instance Functor Music where | ^^^^^^^^^^^^^
也许问题在于我本质上只是为 Duo 的一个子集编写一个 Functor,也许这只有在我使音乐成为一种新类型而不仅仅是类型同义词时才有效。我真的希望避免这种情况,因为这段代码中的包装器数量已经非常多了,我真的不想再添加另一个。也许你们都可以想出一种方法来为 Duo 实现一个有意义的函子,并使这一切都能发挥作用?
我真的不明白的一件事是为什么它让我举一个例子来展示:
instance (Show a) => Show (Music a) where
show (Duo Nothing) = "Silence"
show (Duo (Just (Concurrent x))) = show x