Tôi có một số lượng lớn các vị trí vector chức năng của các loạiphạm trù cho biến kiểu tạm thời
f :: (M.MVector v r, PrimMonad m) =>
v (PrimState m) r -> v (PrimState m) r -> m()
Những chức năng chủ yếu là làm việc tại chỗ, vì vậy nó là thuận tiện để có lập luận của họ là một vector có thể thay đổi để Tôi có thể soạn, lặp lại, v.v. Tuy nhiên, ở cấp cao nhất, tôi chỉ muốn làm việc với các vectơ thuần khiết "Haskell"/thuần túy.
Dưới đây là một ví dụ về các vấn đề:
{-# LANGUAGE TypeFamilies,
ScopedTypeVariables,
MultiParamTypeClasses,
FlexibleInstances #-}
import Data.Vector.Generic as V hiding (eq)
import Data.Vector.Generic.Mutable as M
import Control.Monad.ST
import Control.Monad.Primitive
f :: (M.MVector v r, PrimMonad m) =>
v (PrimState m) r -> v (PrimState m) r -> m()
f vIn vOut = do val <- M.read vIn 0
M.write vOut 0 val
applyFunc :: (M.MVector v r, PrimMonad m, V.Vector v' r, v ~ Mutable v') =>
(v (PrimState m) r -> v (PrimState m) r -> m()) -> v' r -> v' r
applyFunc g x = runST $ do
y <- V.thaw x
g y y -- LINE 1
V.unsafeFreeze y
topLevelFun :: (V.Vector v r) => r -> v r
topLevelFun a =
let x = V.replicate 10 a
in applyFunc f x -- LINE 2
Các mã như kết quả bằng văn bản trong một lỗi trên dòng 1:
Could not deduce (m ~ ST s)
Expected type: ST s()
Actual type: m()
in the return type of g, LINE 1
Bình luận ra dòng 1 kết quả trong các lỗi trên dòng 2:
Ambiguous type variable `m0' in the constraint:
(PrimMonad m0) arising from a use of `applyFun'
Tôi đã thử nhiều cách đánh máy rõ ràng (sử dụng ScopedTypeVariables, foral rõ ràng ls, v.v.) nhưng không tìm được cách sửa chữa lỗi đầu tiên. Đối với lỗi LINE 1, có vẻ như m
chỉ cần được suy ra là ST s
vì tôi đang ở trong một runST
.
Đối với Error Line 2 (với dòng 1 nhận xét ra), điều duy nhất tôi đã đi lên với công trình là
class Fake m v where
kindSig :: m a -> v b c
instance Fake m v
topLevelFun :: forall m v v' r . (V.Vector v' r, M.MVector v r, PrimMonad m, Fake m v, v ~ Mutable v') => r -> v' r
topLevelFun a =
let x = V.replicate 10 a
in applyFunc (f::Transform m v r) x -- LINE 2
mà rõ ràng là không đạt yêu cầu: Tôi có để tạo ra một lớp học giả, với một phương pháp vô nghĩa hơn nữa mà chỉ có công việc là chứng minh các loại đối số của lớp. Sau đó, tôi tạo một trường hợp chung cho tất cả mọi thứ để tôi có thể có m
trong phạm vi trong topLevelFun
, để tôi có thể thêm một ràng buộc và đúc f
. Co cach tôt hơn ma.
Tôi có thể làm nhiều thứ sai ở đây, vì vậy mọi đề xuất sẽ hữu ích.
'applyFunc' hứa sẽ hoạt động với bất kỳ' PrimMonad m' nào mà _caller_ chọn, nhưng sau đó 'runST $ do ...' buộc 'm' thành' ST s'. Bạn có thể sửa lỗi đó bằng cách nói rằng 'g' làm việc cho bất kỳ' PrimMonad m' _you_ nào, hoặc chỉ bằng cách giới hạn 'm' thành' ST s'. Đây là [code] (http://hpaste.org/80991). Nếu điều này thực sự trả lời vấn đề của bạn, hãy cho tôi biết và tôi sẽ viết ra một câu trả lời. – Vitus
Tôi tin điều này hoạt động, với một số thay đổi nhỏ. Hãy chắc chắn để thêm 'Rank2Types' để nhập khẩu ngôn ngữ, và loại rank2 trong 'applyFunc' nên được (forall m. (PrimMonad m) => ...) Rất cám ơn! Rank2Types kéo qua cuối cùng. – crockeea
Ah vâng, tôi đã quên 'RankNTypes' trong' .ghci'. Nhân tiện, tôi tin rằng 'Rank2Types' đang bị phản đối vì lợi ích của' RankNTypes'. – Vitus