gpt4 book ai didi

arrays - 由有界数据类型索引的 Repa 数组?

转载 作者:行者123 更新时间:2023-12-03 13:01:57 24 4
gpt4 key购买 nike

我想实现类似于标准数组包中的有界数组但使用 repa 数组的东西。

实现这一目标的好方法是什么?

这是我尝试过的,但必须有比将所有内容包装在检查边界的自定义函数中更好的方法:

import  Data.Array.Repa

data C = A | F | L deriving (Eq,Enum,Ord,Bounded,Show)

data Ballot c = Ballot {
vote::Array U (Z :. Int) Int
} deriving Show

mkBallot::(Eq c ,Enum c,Ord c, Bounded c, Show c) => c -> Ballot c
mkBallot c = Ballot $ fromListUnboxed (Z :. max) (genSc c)
where
max = (fromEnum (maxBound `asTypeOf` c)) + 1

genSc::(Eq c,Enum c,Ord c,Bounded c,Show c) => c -> [Int]
genSc c = [ f x | x <- enumFrom (minBound `asTypeOf` c) , let f v = if x == c then 1 else 0]

showScore c b = index (vote b) (Z :. ((fromEnum c)))

此外,我尝试为 (sh :. C) 派生一个 Shape 实例,但无济于事,我无法真正了解如何为我的数据类型实现 Shape 类中声明的一些接口(interface)。我正在写这个问题,希望其他人有办法,但如果没有,我会再试一次。谢谢!

最佳答案

您可以为有界枚举周围的包装器创建一个形状实例。我不确定这是最好的方法,但我认为它可以满足您的需求。

{-# LANGUAGE ScopedTypeVariables  #-}

import Data.Array.Repa

在这里,我们在有界事物上创建一个形状实例。我们需要一个“完整”数组的索引结束。
data Idx a = Idx a | EOI
deriving (Eq, Ord, Show)

fromIdx :: forall a . (Bounded a, Enum a) => Idx a -> Int
fromIdx EOI = fromEnum (maxBound :: a) - fromEnum (minBound :: a) + 1
fromIdx (Idx x) = fromEnum x - fromEnum (minBound :: a)

toIdx :: forall a . (Bounded a, Enum a) => Int -> Idx a
toIdx i | i < 0 = error "negative index"
toIdx i = case compare i range of
LT -> Idx $ toEnum (i + fromEnum (minBound :: a))
EQ -> EOI
GT -> error "out of range"
where
range = fromEnum (maxBound :: a) - fromEnum (minBound :: a) + 1

instance (Bounded a, Enum a, Ord a) => Shape (Idx a) where
rank _ = 1
zeroDim = Idx minBound
unitDim = Idx $ succ minBound
intersectDim EOI n = n
intersectDim n EOI = n
intersectDim (Idx n1) (Idx n2) = Idx $ min n1 n2
addDim = error "undefined"
size = fromIdx
sizeIsValid _ = True
toIndex _ n = fromIdx n
fromIndex _ i = toIdx i
inShapeRange _ _ EOI = error "bad index"
inShapeRange n1 n2 n = n >= n1 && n <= n2
listOfShape n = [fromIdx n]
shapeOfList [i] = toIdx i
shapeOfList _ = error "unsupported shape"
deepSeq (Idx n) x = n `seq` x
deepSeq _ x = x

这样,选票部分就简单明了:
data C = A | F | L deriving (Eq, Enum, Ord, Bounded, Show)

data Ballot c = Ballot { vote :: Array U (Idx c) Int
} deriving Show

mkBallot :: (Eq c, Enum c, Ord c, Bounded c, Show c) => c -> Ballot c
mkBallot c = Ballot $ fromListUnboxed EOI vec
where
vec = map (fromEnum . (== c)) [minBound .. maxBound]

关于arrays - 由有界数据类型索引的 Repa 数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12973935/

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