gpt4 book ai didi

haskell - 重新审视具有约束类型的多态 STUArray

转载 作者:行者123 更新时间:2023-12-02 00:23:30 25 4
gpt4 key购买 nike

我想在分数类型上实现一个多态的动态规划算法;这是没有边界条件的简化一维版本:

{-# LANGUAGE ConstraintKinds, FlexibleContexts, RankNTypes, ScopedTypeVariables #-}

import Control.Monad
import Control.Monad.ST.Strict
import Data.Array.ST
import Data.Array.Unboxed

dynamicProgrammingSTU
:: forall e i . (
IArray UArray e,
forall s. MArray (STUArray s) e (ST s),
Ix i
)
=> (forall m . Monad m => (i -> m e) -> (i -> m e))
-> (i, i)
-> (i -> e)
dynamicProgrammingSTU prog bnds = (arr !) where
arr :: UArray i e
arr = runSTUArray resultArrayST

resultArrayST :: forall s . ST s (STUArray s i e)
resultArrayST = do
marr <- newArray_ bnds
forM_ (range bnds) $ \i -> do
result <- prog (readArray marr) i
writeArray marr i result
return marr

约束不起作用;

    Could not deduce (MArray (STUArray s) e (ST s))
arising from a use of `newArray_'
from the context (IArray UArray e,
forall s. MArray (STUArray s) e (ST s),
Ix i)
bound by the type signature for
dynamicProgrammingSTU :: (IArray UArray e,
forall s. MArray (STUArray s) e (ST s
), Ix i) =>
(forall (m :: * -> *). Monad m => (i -
> m e) -> i -> m e)
-> (i, i) -> i -> e
at example2.hs:(17,1)-(27,15)
Possible fix:
add (MArray (STUArray s) e (ST s)) to the context of
the type signature for resultArrayST :: ST s (STUArray s i e)
or the type signature for
dynamicProgrammingSTU :: (IArray UArray e,
forall s. MArray (STUArray s) e (ST s), I
x i) =>
(forall (m :: * -> *). Monad m => (i -> m
e) -> i -> m e)
-> (i, i) -> i -> e
or add an instance declaration for (MArray (STUArray s) e (ST s))
In a stmt of a 'do' block: marr <- newArray_ bnds
In the expression:
do { marr <- newArray_ bnds;
forM_ (range bnds) $ \ i -> do { ... };
return marr }
In an equation for `resultArrayST':
resultArrayST
= do { marr <- newArray_ bnds;
forM_ (range bnds) $ \ i -> ...;
return marr }
Failed, modules loaded: none.

总而言之,无法从 forall s 的上下文中推导出 (MArray (STUArray s) e (ST s))。 MArray (STUArray s) e (ST s i)。请注意,将约束添加到 resultArrayST 只会将问题推向 runSTUArray

我目前知道四个有缺陷的解决方案:

  1. 避免盒装 STArray 或简单的非单元 Array 的问题,也许可以使用 seq 和 bang 模式来缓解内存占用问题问题。
  2. 使用 unsafeFreezeunsafePerformIO 打破类型系统,对于该系统,该死的约束 MArray IOUArray e IO 工作得很好。
  3. This使用类型类并为每个“可拆箱”类型编写实例来解决类似问题。
  4. This使用 GHC 重写规则为每种类型选择不同的函数(以及通用 STArray 版本)。

但是,我问这个问题是希望像 ConstraintKinds 这样的现代语言扩展可以让我表达我的原始代码的 forall 意图。 MArray (STUArray s) e (ST s).

最佳答案

鉴于 Haskell 社区的传奇般的帮助,目前缺乏答案强烈表明当前类型系统中没有好的解决方案。

我已经概述了问题中存在缺陷的解决方案,因此我将发布示例的完整版本。这基本上是我用来解决 Rosalind 上大多数对齐问题的方法:

{-# LANGUAGE FlexibleContexts, RankNTypes, ScopedTypeVariables #-}

import Control.Applicative
import Control.Monad
import Control.Monad.ST
import Data.Maybe

import Data.Array.ST
import Data.Array.Unboxed

class IArray UArray e => Unboxable e where
newSTUArray_ :: forall s i. Ix i => (i, i) -> ST s (STUArray s i e)
readSTUArray :: forall s i. Ix i => STUArray s i e -> i -> ST s e
writeSTUArray :: forall s i. Ix i => STUArray s i e -> i -> e -> ST s ()


instance Unboxable Bool where
newSTUArray_ = newArray_
readSTUArray = readArray
writeSTUArray = writeArray

instance Unboxable Double where
newSTUArray_ = newArray_
readSTUArray = readArray
writeSTUArray = writeArray
{-
Same for Char, Float, (Int|Word)(|8|16|32|64)...
-}

{-# INLINE dynamicProgramming2DSTU #-}
dynamicProgramming2DSTU
:: forall e i j . (
Unboxable e,
Ix i,
Ix j,
Enum i,
Enum j
)
=> (forall m . (Monad m, Applicative m) => (i -> j -> m e) -> (i -> j -> m e))
-> (i -> j -> Maybe e)
-> (i, i)
-> (j, j)
-> (i -> j -> e)
dynamicProgramming2DSTU program boundaryConditions (xl, xh) (yl, yh) = arrayLookup where
arrayLookup :: i -> j -> e
arrayLookup xi yj = fromMaybe (resultArray ! (xi, yj)) $ boundaryConditions xi yj

arrB :: ((i, j), (i, j))
arrB = ((xl, yl), (xh, yh))

resultArray :: UArray (i, j) e
resultArray = runSTUArray resultArrayST

resultArrayST :: forall s. ST s (STUArray s (i, j) e)
resultArrayST = do
arr <- newSTUArray_ arrB
let acc xi yj = maybe (readSTUArray arr (xi, yj)) return $ boundaryConditions xi yj

forM_ [xl..xh] $ \xi -> do
forM_ [yl..yh] $ \yj -> do
result <- program acc xi yj
writeSTUArray arr (xi, yj) result

return arr

关于haskell - 重新审视具有约束类型的多态 STUArray,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15311872/

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