如何制作Applicative的固定长度向量实例?

2024-04-30

最近了解了推广,决定尝试写向量。

{-# LANGUAGE DataKinds, GADTs, KindSignatures #-}
module Vector where
  data Nat = Next Nat | Zero
  data Vector :: Nat -> * -> * where
    Construct :: t -> Vector n t -> Vector ('Next n) t
    Empty :: Vector 'Zero t
  instance Functor (Vector n) where
    fmap f a =
      case a of
        Construct x b -> Construct (f x) (fmap f b)
        Empty -> Empty

到目前为止,一切正常。但我在尝试制作时遇到了问题Vector的实例Applicative.

instance Applicative (Vector n) where
  a <*> b =
    case a of
      Construct f c ->
        case b of
          Construct x d -> Construct (f x) (c <*> d)
      Empty -> Empty
  pure x = _

我不知道该怎么做pure。我试过这个:

case n of
  Next _ -> Construct x (pure x)
  Zero -> Empty

but got Variable not in scope: n :: Nat第一行的错误和Couldn't match type n with 'Zero对于这个表达式的第三行。

所以,我使用了以下技巧。

class Applicative' n where
  ap' :: Vector n (t -> u) -> Vector n t -> Vector n u
  pure' :: t -> Vector n t
instance Applicative' n => Applicative' ('Next n) where
  ap' (Construct f a) (Construct x b) = Construct (f x) (ap' a b)
  pure' x = Construct x (pure' x)
instance Applicative' 'Zero where
  ap' Empty Empty = Empty
  pure' _ = Empty
instance Applicative' n => Applicative (Vector n) where
  (<*>) = ap'
  pure = pure'

它完成了工作,但并不漂亮。它引入了一个无用的类Applicative'。每次我想使用Applicative for Vector在任何函数中,我都必须提供额外的无用约束Applicative' n这实际上适用于任何n.

更好、更干净的方法是什么?


你可以直接做同样的事情:

instance Applicative (Vector Zero) where
  a <*> b = Empty
  pure x = Empty

instance Applicative (Vector n) => Applicative (Vector (Next n)) where
  a <*> b = 
    case a of
      Construct f c ->
        case b of
          Construct x d -> Construct (f x) (c <*> d)
  pure x = Construct x (pure x)

我可以推断:对于不同类型的类,代码应该是类型感知的。如果你有多个实例,不同的类型会得到不同的实现,这很容易解决。但是,如果您尝试使用单个非递归实例来实现,则运行时基本上没有有关类型的信息,并且始终相同的代码仍然需要决定要处理哪种类型。当您有输入参数时,您可以利用 GADT 来提供类型信息。但对于pure没有输入参数。所以你必须有一些背景Applicative实例。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何制作Applicative的固定长度向量实例? 的相关文章

  • Haskell 中的前提条件检查有哪些选项

    这是一个简单的问题 我认为答案很复杂 一个非常常见的编程问题是函数返回某些内容 或者前置条件检查失败 在Java中 我会使用一些抛出异常的断言函数IllegalArgumentException在方法的开头 如下所示 method body
  • 如何为强制长度为 2^n 的向量类型定义可用的 Applicative 实例

    对于某些应用程序 我需要长度为 2 n 的向量 为了强制某些操作的长度匹配 我使用 ist 应用实例定义了我的类型 如下所示 LANGUAGE GADTs DataKinds FlexibleInstances FlexibleContex
  • 如何让 Show 显示函数名称?

    作为一个让我熟悉 Haskell 的简单练习 在 Youtube 上闲逛并偶然进入美国倒计时游戏节目之后 我想为数字游戏制作一个求解器 你得到 6 个数字 需要将它们与 为了得到给定的结果 到目前为止我所得到的是非常脑死亡的 let ope
  • 在 Haskell 中计算移动平均线

    我正在学习 Haskell 所以我尝试实现移动平均函数 这是我的代码 mAverage Int gt Int gt Float mAverage x a fromIntegral k fromIntegral x k lt rawAvera
  • 这个记忆的斐波那契函数是如何工作的?

    在我正在做的函数式编程课程的当前练习作业中 我们必须制作给定函数的记忆版本 为了解释记忆化 给出以下示例 fiblist fibm x x lt 0 fibm 0 0 fibm 1 1 fibm n fiblist n 1 fiblist
  • 我应该在 Turtle 或 Foldl 包中使用折叠吗?

    我在使用 Turtle 时遇到了一些困难 直到盯着难以理解的错误消息几分钟后才意识到我使用了错误的fold功能 https hackage haskell org package turtle 1 5 8 docs Turtle Shell
  • 持久 selectList 导致错误“无法将类型‘BaseBackend backend0’与‘SqlBackend’匹配”

    我遇到以下编译错误 Couldn t match type BaseBackend backend0 with SqlBackend arising from a use of runSqlite The type variable bac
  • 您可以传递“类型”作为参数吗?

    我想在 VB NET 中做类似以下的事情 可以吗 Function task value as Object toType as Type Return DirectCast value toType End Function 是的 有系统
  • Haskell:是的,没有类型类。为什么是整数?

    我有一个关于 GHCi 如何假定整数类型的问题 我正在阅读 Learn you a Haskell 是 否类型的课程 如果您想阅读全文 这里有一个链接 http learnyouahaskell com making our own typ
  • 搜索重写规则

    有什么办法可以浏览或搜索重写规则吗 当我使用像这样的标志时 ddump rule firings or ddump rule rewrites我只是得到了触发的规则的名称以及它引起的重写 但没有得到实际的规则本身 理想情况下 我想通过 GH
  • Haskell,堆栈:找到可执行文件

    我正在寻找类似的东西 stack whereis hasktags where whereis行为或多或少类似于 UNIXwhereis命令 hasktags是这样运行的 stack exec hasktags stack exec whe
  • 规范化且不可变的数据模型

    Haskell如何解决 规范化不可变数据结构 问题 例如 让我们考虑一个表示前女友 男友的数据结构 data Man Man name String exes Woman data Woman Woman name String exes
  • Haskell 中列表列表的笛卡尔积

    给定一个长度列表的列表x所有子列表的长度都相同y 输出y x长度列表x包含每个子列表中的一项 例子 x 3 y 2 1 2 3 4 5 6 Output 2 3 8不同的输出 1 3 5 1 4 5 1 3 6 1 4 6 2 3 5 2
  • 在scala 2.13中,为什么有时无法显式调用类型类?

    这是 Shapeless 2 3 3 中的一个简单示例 val book author gt gt Benjamin Pierce title gt gt Types and Programming Languages id gt gt 2
  • 如何在 Haskell 中漂亮地打印表格?

    我想在 Haskell 中漂亮地打印一个类似表格的数据结构 列列表 例如 Table StrCol strings a bc c IntCol ints 1 30 2 DblCol doubles 2 0 4 5 3 2 应该渲染类似 st
  • Haskell 入门

    这个问题的答案是社区努力 help privileges edit community wiki 编辑现有答案以改进这篇文章 目前不接受新的答案或互动 几天来 我一直试图理解 Haskell 中的函数式编程范例 我通过阅读教程和观看截屏视频
  • 有没有更好的方法将 UTC 时间转换为大纪元时间?

    我想将文件的修改时间设置为从 exif 数据获取的时间 为了从 exif 获取时间 我发现 Graphics Exif getTag Exif gt String gt IO Maybe String 要设置文件修改时间 我发现 Syste
  • QuickCheck是否可以生成任意函数

    我试图为身份编写一个 QuickCheck 测试 f y f y 我最初的计划是编写一个返回函数和整数的任意生成器 具有签名Gen Int gt Int Int 并在prop DollerDoesNothing使用 不使用测试该功能应用程序
  • Haskell:IORef 的性能

    我一直在尝试在 Haskell 中编码一个需要使用大量可变引用的算法 但与纯粹的惰性代码相比 它 也许并不奇怪 非常慢 考虑一个非常简单的例子 module Main where import Data IORef import Contr
  • Haskell 输入返回元组

    我想知道 IO 函数是否可以返回元组 因为我想从这个函数中获取这些元组作为另一个函数的输入 investinput IO gt Char Int investinput do putStrLn Enter Username username

随机推荐