警卫

2017-07-11 68 views
0

哈斯克尔替代类和虚函数可以说我有以下ADT,警卫

data Properties a = Property String a 
    deriving (Show,Eq) 

我已经做了以下情况吧,

instance Functor Properties where 
    fmap f (Property name prop) = Property name (f prop) 
-- 
instance Applicative (Properties) where 
    pure a = Property "" a 
    (Property _ f) <*> p = fmap f p 

instance Monad (Properties) where 
    return a = Property "" a 
    (Property name prop) >>= f = (f prop) 

到目前为止好。让我们看看我们可以迄今为止做,

pColors = Property "Color" ["Blue", "Red", "White"] 
pNationality = Property "Nationality" ["Italian", "Norwegian", "Spanish"] 

answers = do 
    color <- fmap permutations pColors 
    nation <- fmap permutations pNationality 
    return $ zip color nation 

给人,

*Main> answers 
Property "" [(["Blue","Red","White"],["Italian","Norwegian","Spanish"]),(["Red","Blue","White"],["Norwegian","Italian","Spanish"]),(["White","Red","Blue"],["Spanish","Norwegian","Italian"]),(["Red","White","Blue"],["Norwegian","Spanish","Italian"]),(["White","Blue","Red"],["Spanish","Italian","Norwegian"]),(["Blue","White","Red"],["Italian","Spanish","Norwegian"])] 

所以fmap和预期的单子绑定都在工作。现在我想使用alternative中的guard函数。基本上我想根据一些谓词修剪pColorspNationality。所以我尝试定义,

instance Alternative (Properties) where 
    empty = Property "" [] 

但是,这给了我一个错误,我认为(请纠正我,如果我错了),这是因为Haskell是解释[]a不同。但我认为a可能是任何东西,而[]是其中之一,所以问题是什么?

+0

如果您使用'{ - #LANGUAGE GeneralizedNewtypeDivingiving# - }' – 4castle

+0

您可以执行'newtype属性a =属性(String,a)派生(Show,Eq,Functor,Applicative,Monad)'上面的ADT?如果我编写'newtype Property a = String a derivation(Show,Eq,Functor,Applicative,Monad)',它自己假设(避免多个'Property'的声明)'给出一个错误,Functor不能派生出来并且不得不使用'DerivedFunctor'。 – ITA

+0

并加入'DerivedFunctor'则误差变, '不能让“应用型住宅” (甚至狡猾GeneralizedNewtypeDeriving)的衍生实例: 不能ETA-减少表示类型enough' – ITA

回答

4

但我认为a可以是任何东西和[]是任何一个,所以有什么问题?

不是说a可以是任何东西,但是a必须能够是任何东西。这是如果用户写入x :: Property [a]; x = empty,那必须被允许,但是x :: Property Int; x = empty也必须被允许。你的定义只允许前者,所以这是不正确的。

没有办法定义有效emptyProperty类型,除非你让它产生错误(如empty = Property "" undefined)或改变的Property定义添加一个案例的空属性。

+0

谢谢,有没有一个'Listable'类的类约束,我可以给'a'? – ITA

+1

@IvanAbraham有一个['IsList'](https://hackage.haskell.org/package/base-4.9.0.0/docs/GHC-Exts.html#t:IsList)typeclass,但是没有办法添加' IsList a =>'作为'empty'的约束。 'Alternative'要求*任何*类型都可以用作'a'中的'a'。 – 4castle

+0

@ 4Castle它是否与'ConstraintKinds'一起使用?我的目标是为dataType定义'Alternative'。 '未定义'技巧与'空'一起工作(稍后可能会有所改变)。但对于'<|>'我只想在元组的第二个元素上做'++'(就像在你以前的评论中一样)。 – ITA