表示在Haskell中表示固定尺寸网格的意识形态方法

发布于 2025-02-02 17:25:01 字数 402 浏览 0 评论 0原文

我发现有些奇怪的是,代表固定大小的数组 /网格而不诉诸库(固定长度 /固定矢量)似乎很棘手,而这些库似乎相对笨拙。

我想做类似于此Rust Code(对于国际象棋板)类似的事情:

const N: usize = 8;

struct Piece {}

struct Board {
    data: [[Piece; N]; N]
}

在Haskell中执行此操作的惯用方法是什么?为什么代表固定尺寸的阵列似乎很难?

理想的代码看起来像:

data Board (n :: Natural) = Board (Array Piece n)

但是我想问题是它需要n构造函数的其他参数,我必须手工键入?

Something I've found a little odd, is that it seems tricky to represent a fixed size array / grid without resorting to libraries (fixed-length / fixed-vector.) And those libraries, from a glance, seem relatively clunky.

I want to do something similar to this Rust code (for a chess board):

const N: usize = 8;

struct Piece {}

struct Board {
    data: [[Piece; N]; N]
}

What is the idiomatic way to do this in Haskell? And why does it seem so difficult to represent fixed sized arrays?

The ideal code would look something like:

data Board (n :: Natural) = Board (Array Piece n)

But I guess the problem there is that it would need n additional parameters for the constructor, which I'd have to type out by hand?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

画▽骨i 2025-02-09 17:25:01

网格软件包看起来不错,但似乎没有正确设置它的依赖项。

我忘记了矢量大小的软件包,这似乎正是我想要的。不幸的是,它在运行时存储了大小,但这不是真正的问题。

该代码似乎效果很好:

{-# LANGUAGE DataKinds #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE TypeApplications #-}

module Main where

import Data.Vector.Sized
import GHC.TypeLits
import Prelude hiding (replicate)

data Piece = Piece
    deriving (Show)

newtype Board (n :: Natural) = Board (Vector n (Vector n Piece))
    deriving (Show)

newBoard :: Board 8
newBoard = Board $ replicate @8 $ replicate @8 Piece

main :: IO ()
main = print $ newBoard

The grids package looked pretty good, but it's dependencies didn't seem to be set up correctly.

I'd forgotten about the vector-sized package, which seems to be exactly what I want. Unfortunately it stores the size at runtime but that's not a real issue.

This code seems to work nicely:

{-# LANGUAGE DataKinds #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE TypeApplications #-}

module Main where

import Data.Vector.Sized
import GHC.TypeLits
import Prelude hiding (replicate)

data Piece = Piece
    deriving (Show)

newtype Board (n :: Natural) = Board (Vector n (Vector n Piece))
    deriving (Show)

newBoard :: Board 8
newBoard = Board $ replicate @8 $ replicate @8 Piece

main :: IO ()
main = print $ newBoard
一刻暧昧 2025-02-09 17:25:01

如果您的n在编译时间且小(在这里,听起来像是固定为8),并且您不介意一些额外的打字,那么您可以简单地定义一个完全具有您的字段数量的新类型想要,所有类型的类型。我希望这种方法不会给出良好的随机访问时间或良好的更新时间,但是它非常简单,显然是正确的,并且易于实现。我不能说,这些是否是您情况的良好权衡。

data Eight a = Eight a a a a a a a a
  deriving (Show, Functor, Foldable, Traversable)
instance Applicative Eight where
  pure x = Eight x x x x x x x x
  Eight fa fb fc fd fe ff fg fh <*> Eight a b c d e f g h =
    Eight (fa a) (fb b) (fc c) (fd d) (fe e) (ff f) (fg g) (fh f)
newtype SixtyFour a = SixtyFour (Eight (Eight a))
  deriving (Show, Functor, Foldable, Traversable)

您可以想象,尽管再次乏味,但很容易为特定索引提供配件和更新器。

If your N is fixed at compile time and small (here, it sounds like it's fixed to 8), and you don't mind a little bit of extra typing, you can simply define a new type that has exactly the number of fields you want, all of the same type. I expect this approach does not give good random-access time, or good update time, but it is very simple, obviously correct, and easy to implement yourself. Whether those are good tradeoffs for your situation, I couldn't say.

data Eight a = Eight a a a a a a a a
  deriving (Show, Functor, Foldable, Traversable)
instance Applicative Eight where
  pure x = Eight x x x x x x x x
  Eight fa fb fc fd fe ff fg fh <*> Eight a b c d e f g h =
    Eight (fa a) (fb b) (fc c) (fd d) (fe e) (ff f) (fg g) (fh f)
newtype SixtyFour a = SixtyFour (Eight (Eight a))
  deriving (Show, Functor, Foldable, Traversable)

As you can imagine, it is easy, although again tedious, to provide accessors and updaters for particular indices.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文