import qualified Prelude
class List list where
toList :: list a -> [a]
fromList :: [a] -> list a
data Deque a = Deque [a] [a]
instance List Deque where
toList (Deque xs sy) = xs reverse sy
fromList xs = Deque ys (reverse zs)
where (ys, zs) = splitAt (length xs `div` 2) xs
我收到一個錯誤,如下所示。GHCI 似乎沒有檢測ys為 Deque,而是作為 List 類的一般實體。
ghci> xs = [2, 3, 4]
ghci> ys = fromList xs
ghci> (Deque a b) = ys
ghci> toList (Deque a b)
[2,3,4]
ghci> toList ys
<interactive>:5:1: error:
* Could not deduce (List list0) arising from a use of `toList'
from the context: Num a
bound by the inferred type of it :: Num a => [a]
at <interactive>:5:1-9
The type variable `list0' is ambiguous
These potential instance exist:
instance [safe] List Deque -- Defined at main.hs:12:10
* In the expression: toList ys
In an equation for `it': it = toList ys
uj5u.com熱心網友回復:
ghci> let xs = [2, 3, 4]
ghci> let ys = fromList ys
此時,這些值可能具有最通用的類??型:
ghci> :t xs
xs :: Num a => [a]
ghci> :t ys
ys :: (List list, Num a) => list a
沒有暗示 a Deque,這是有道理的,因為您還沒有提到任何雙端佇列。
但是這些變數保持不變,它們不會改變它們的型別!
所以之后
ghci> (Deque a b) = ys
ghci> toList (Deque a b)
[2,3,4]
你仍然有同樣的情況ys,即
ghci> :t ys
ys :: (List list, Num a) => list a
當然,您曾經用作ys雙端佇列,這是可以使用的一種方式。但由于是多型的,它也可以是任何其他List型別,GHCi 不會做出任何猜測它應該是什么。但你當然可以告訴它:
ghci> toList (ys :: Deque Int)
[2,3,4]
或者更短
ghci> :set -XTypeApplications
ghci> toList @Deque ys
[2,3,4]
uj5u.com熱心網友回復:
這是按設計作業的。當你寫:
λ> ys = fromList xs
分配給的型別ys是:
λ> :t ys
ys :: (List list, Prelude.Num a) => list a
也就是說,ys是一個多型值,可以“是”任何型別的List.
因此,當您將其系結到特定模式時:
λ> Deque a b = ys
thenys被實體化為 aDeque并且適當的值系結到aand b,但這不會使ys單態。也就是說,ys還沒有突然“變成”一個Deque. 相反,它仍然是一個多型值,可以反彈到其他一些List. 例如,如果您還有一個普通舊串列的實體:
instance List [] where
toList = id
fromList = id
您可以實體化ys多種型別:
λ> xs = [2, 3, 4]
λ> ys = fromList xs
λ> Deque a b = ys -- instantiate as Deque
λ> c:d = ys -- instantiate as []
如果這讓您感到奇怪,請考慮:
λ> id "hello"
λ> id 'x'
兩者都有效,即使第一次使用多型值id :: a -> a,它也被實體化為String -> String,而第二次使用時,它被實體化為Char -> Char. 這是相同的原理。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/406353.html
標籤:
