yai*_*chu 5 haskell type-families
我做了一个类似于numpy的功能array.它将列表转换为数组,将列表列表转换为2d数组等.
它的工作原理如下:
ghci> arrFromNestedLists ["hello", "world"] :: Array (Int, (Int, ())) Char
array ((0,(0,())),(1,(4,()))) [((0,(0,())),'h'),((0,(1,())),'e'),((0,(2,())),'l'),((0,(3,())),'l'),((0,(4,())),'o'),((1,(0,())),'w'),((1,(1,())),'o'),((1,(2,())),'r'),((1,(3,())),'l'),((1,(4,())),'d')]
Run Code Online (Sandbox Code Playgroud)
(Int, (Int, ()))而不是(Int, Int)因为我不知道增加元组长度的程序方法.(旁边的问题:有这样的方式吗?)
它的编码很尴尬,我不得不做一个"解决方法"(将伪参数传递给函数)以使其工作.我想知道是否有更好的方法.
所以这是代码,中断了丑陋的变通方法的细节:
{-# LANGUAGE FlexibleInstances, ScopedTypeVariables, TypeFamilies #-}
type family ListOfIndex i a
type instance ListOfIndex () a = a
type instance ListOfIndex (Int, i) a = [ListOfIndex i a]
class Ix i => ArrConv i where
acBounds :: a -> ListOfIndex i a -> (i, i)
acFlatten :: i -> ListOfIndex i a -> [a]
Run Code Online (Sandbox Code Playgroud)
acBounds"应该" :: ListOfIndex i a -> (i, i).同样的acFlatten.每个都给出一个虚拟变量(undefined总是给出的值)因为否则我无法得到它编译:(
arrFromNestedLists :: forall i a. ArrConv i => ListOfIndex i a -> Array i a
arrFromNestedLists lst =
listArray
(acBounds (undefined :: a) lst)
(acFlatten (undefined :: i) lst)
Run Code Online (Sandbox Code Playgroud)
以上是undefined在工作中传递的虚拟参数.它告诉GHC使用哪个实例ListOfIndex.
instance ArrConv () where
acBounds _ = const ((), ())
acFlatten _ = (: [])
Run Code Online (Sandbox Code Playgroud)
下面的函数应该acBounds是实例中的函数ArrConv,并且只是因为我需要使用ScopedTypeVariables而在外部声明,我不知道如何在实例定义中的函数中执行它.
acSucBounds
:: forall a i. ArrConv i
=> a -> [ListOfIndex i a] -> ((Int, i), (Int, i))
acSucBounds _ lst =
((0, inStart), (length lst - 1, inEnd))
where
(inStart, inEnd) = acBounds (undefined :: a) (head lst)
instance ArrConv i => ArrConv (Int, i) where
acBounds = acSucBounds
acFlatten _ = concatMap (acFlatten (undefined :: i))
Run Code Online (Sandbox Code Playgroud)
acBounds 和 acFlatten 的额外参数是必要的,因为类型a和无法分别从和i恢复。一种解决方法是将这两种方法合并为一种type方法。现在唯一的问题是在 实例中使用它,以防止类型检查器过度泛化其类型,从而导致与以前相同的问题(例如,我们不能简单地使用)。ListOfIndex i a -> (i, i)ListOfIndex i a -> [a]acArgsListOfIndex i a -> ((i, i), a)(Int, i)fst . acArgs
{-# LANGUAGE TypeFamilies、FlexibleInstances #-}
导入数据.Array
类型族 ListOfIndex ia
类型实例ListOfIndex() a = a
类型实例 ListOfIndex (Int, i) a = [ListOfIndex ia]
类 Ix i => ArrConv i 其中
acArgs :: ListOfIndex ia -> ((i, i), [a])
实例 ArrConv () 其中
acArgs x = (((), ()), [x])
实例 ArrConv i => ArrConv (Int, i) 其中
acArgs lst =
(((0, inStart), (长度 lst - 1, inEnd)), args >>= snd)
在哪里
args = 映射 acArgs lst
(inStart, inEnd) = fst (头参数)
arrFromNestedLists :: ArrConv i => ListOfIndex ia -> 数组 ia
arrFromNestedLists = uncurry listArray 。参数