2017-10-14 52 views
1

The following code一類產生「預期的約束」錯誤:如何定義與一種類型的家庭

{-# LANGUAGE TypeFamilies #-} 
{-# LANGUAGE ExistentialQuantification #-} 

type family Note a 
type instance Note String = String 

data SomeNote = forall a. Note a => SomeNote a 

class HasNote b where 
    noteOf :: b -> SomeNote 

該錯誤是Expected a constraint, but 'Note a' has kind '*', in the definition of SomeNote。爲什麼?我該如何解決它?

目標是在某些數據結構b中包含Note類型的實例,並使用noteOf b提取它,無論實例是什麼。

回答

3

我們的目標是爲包括注型家庭的一些數據結構B的實例,並使用noteOf b鍵提取它

這不是類型的家庭是如何工作的。您剛纔所說的是,您可以通過類型函數Note將由變量a表示的一種類型映射到另一種類型。這並不意味着a類型的值完全包含Note b類型的值。它是類型類相當強烈意味着Note a類型在a類型內或可從中計算。

的代碼是沿着線:

type family Note a 
type instance Note String = String 
class SomeNote a where 
    noteOf :: a -> Note a 

更妙的是,可以考慮使用一個相關類型:

{-# LANGUAGE DataKinds #-} 
{-# LANGUAGE FlexibleInstances #-} 

class SomeNote a where 
    type Note a :: * 
    noteOf :: a -> Note a 

instance SomeNote String where 
    type Note String = String 
    noteOf = id