一千萬個為什麽

搜索

在Haskell中鍵入模式

我正在嘗試編譯泛型類/類型模式的簡單示例(參見 http://www.haskell.org/ghc/docs/latest/html/users_guide/generic-classes.html )但它不會編譯。關於代碼有什麽問題的任何想法都會有所幫助。

根據文檔,應該有一個模塊 Generics ,數據類型為 Unit:*::+:</代碼>但ghc(6.12.1)抱怨不在範圍內:數據構造函數'Unit'等

看起來有一個包即時泛型,數據類型為:*::+:U ,但是當我導入該模塊時(而不是 Generics )我得到了錯誤

Illegal type pattern in the generic bindings
    {myPrint _ = ""}

完整的源代碼是

import Generics.Instant

class MyPrint a where
  myPrint :: a -> String

  myPrint {| U |} _ = "" 
  myPrint {| a :*: b |} (x :*: y) = "" (show x) ++ ":*:" ++ (show y)
  myPrint {| a :+: b |} _ = ""


data Foo = Foo String

instance MyPrint a => MyPrint a

main = myPrint $ Foo "hi"

我用它編譯它

ghc --make Foo.hs -fglasgow-exts -XGenerics -XUndecidableInstances

附:模塊 Generics 導出沒有數據類型,只有函數:

canDoGenerics
mkGenericRhs
mkTyConGenericBinds
validGenericInstanceType
validGenericMethodType

最佳答案

好吧,我對generics知之甚少,但你要找的符號都在 Data.Generics 模塊中,所以我做了

import Data.Generics

第二,行

myPrint {| a :*: b |} (x :*: y) = "" (show x) ++ ":*:" ++ (show y)

有兩個問題:第一,“”顯然太多了。其次,您不能使用 show ,因為使用的類型不一定是 Show 類型類的實例。所以我做了這一行

myPrint {| a :*: b |} (x :*: y) = (myPrint x) ++ ":*:" ++ (myPrint y)

最後,用

instance MyPrint a => MyPrint a

首先要求 aMyPrint 的一個實例,然後要求編譯器為 aMyPrint 實例>你需要已經存在。這對我有用:

instance MyPrint Foo

但是,您必須首先手動為 String 提供實例,以便編譯器具有派生的起點:

instance MyPrint String where
  myPrint s = s

希望有所幫助。

轉載註明原文: 在Haskell中鍵入模式