AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / coding / 问题 / 76933358
Accepted
New_Caird
New_Caird
Asked: 2023-08-19 10:27:20 +0800 CST2023-08-19 10:27:20 +0800 CST 2023-08-19 10:27:20 +0800 CST

为类型同义词编写函子实例并感到困惑

  • 772

我正在尝试实现一个通用的类似环形的东西,并将其应用于 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
haskell
  • 1 1 个回答
  • 39 Views

1 个回答

  • Voted
  1. Best Answer
    Daniel Wagner
    2023-08-19T10:34:32+08:002023-08-19T10:34:32+08:00

    不幸的是,Haskell 中不允许这种类型级别的抽象。但我认为您可能在数据类型设计中的某个地方犯了某种概念错误。扩展类型,因为Duo只有一个字段,我们将有:

    Music a ~= Duo (Maybe (Concurrent a)) (Maybe (Sequential a))
            ~= Maybe (Concurrent a)
            ~= Maybe (Song a)
    

    这真的是你的意图吗?

    万一发生这种情况,我想我会很想去掉中间商。

    data Music a = Silence | Sound (Song a)
    instance Functor Music where
        fmap f Silence = Silence
        fmap f (Sound notes) = Sound (fmap f notes)
    

    如果这是预期的行为,但你必须保留中间人,newtype这就是前进的方向。

    如果这可能不是您想要的Music行为方式,我们可能会给您更多/更好的建议,但我们需要更多地了解您的意图Duo。

    关于您的编辑/评论Show:在您的Show实例中,您包含一个类型参数Music。该实例的问题正是您不包含参数的Functor事实。在实例中,由于参数可用,编译器可以简单地扩展类型别名,因此该行Show

    instance Show a => Show (Music a)
    

    编译器关心的各方面都与该行相同

    instance Show a => Show (Duo (Maybe (Concurrent a)) (Maybe (Sequential a)))
    

    但是,在您的Functor实例中,编译器无法扩展类型别名,因为您尚未提供类型参数。你可以想象在 Haskell 中添加类型级别的 lambda,这样你的instance Functor Music意思就可以是这样的

    instance Functor (\a -> Duo (Maybe (Concurrent a)) (Maybe (Sequential a)))
    

    但这有一些严重的问题。添加它的天真方式导致您需要在类型检查期间进行高阶统一,这是不可判定的。

    • 4

相关问题

  • Haskell 模数类似于 JavaScript(考虑符号并且适用于非整数)

  • Haskell 中的 scanl 如何在 Either 列表上工作 - 两种情况的比较

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    使用 <font color="#xxx"> 突出显示 html 中的代码

    • 2 个回答
  • Marko Smith

    为什么在传递 {} 时重载解析更喜欢 std::nullptr_t 而不是类?

    • 1 个回答
  • Marko Smith

    您可以使用花括号初始化列表作为(默认)模板参数吗?

    • 2 个回答
  • Marko Smith

    为什么列表推导式在内部创建一个函数?

    • 1 个回答
  • Marko Smith

    我正在尝试仅使用海龟随机和数学模块来制作吃豆人游戏

    • 1 个回答
  • Marko Smith

    java.lang.NoSuchMethodError: 'void org.openqa.selenium.remote.http.ClientConfig.<init>(java.net.URI, java.time.Duration, java.time.Duratio

    • 3 个回答
  • Marko Smith

    为什么 'char -> int' 是提升,而 'char -> Short' 是转换(但不是提升)?

    • 4 个回答
  • Marko Smith

    为什么库中不调用全局变量的构造函数?

    • 1 个回答
  • Marko Smith

    std::common_reference_with 在元组上的行为不一致。哪个是对的?

    • 1 个回答
  • Marko Smith

    C++17 中 std::byte 只能按位运算?

    • 1 个回答
  • Martin Hope
    fbrereto 为什么在传递 {} 时重载解析更喜欢 std::nullptr_t 而不是类? 2023-12-21 00:31:04 +0800 CST
  • Martin Hope
    比尔盖子 您可以使用花括号初始化列表作为(默认)模板参数吗? 2023-12-17 10:02:06 +0800 CST
  • Martin Hope
    Amir reza Riahi 为什么列表推导式在内部创建一个函数? 2023-11-16 20:53:19 +0800 CST
  • Martin Hope
    Michael A fmt 格式 %H:%M:%S 不带小数 2023-11-11 01:13:05 +0800 CST
  • Martin Hope
    God I Hate Python C++20 的 std::views::filter 未正确过滤视图 2023-08-27 18:40:35 +0800 CST
  • Martin Hope
    LiDa Cute 为什么 'char -> int' 是提升,而 'char -> Short' 是转换(但不是提升)? 2023-08-24 20:46:59 +0800 CST
  • Martin Hope
    jabaa 为什么库中不调用全局变量的构造函数? 2023-08-18 07:15:20 +0800 CST
  • Martin Hope
    Panagiotis Syskakis std::common_reference_with 在元组上的行为不一致。哪个是对的? 2023-08-17 21:24:06 +0800 CST
  • Martin Hope
    Alex Guteniev 为什么编译器在这里错过矢量化? 2023-08-17 18:58:07 +0800 CST
  • Martin Hope
    wimalopaan C++17 中 std::byte 只能按位运算? 2023-08-17 17:13:58 +0800 CST

热门标签

python javascript c++ c# java typescript sql reactjs html

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve