通过GeneralizedNewtypeDeriving获取实例时使用自定义实例 [英] Using custom instance when deriving an instance via GeneralizedNewtypeDeriving
问题描述
class(A a,B a)=> C a where
。使用 newtype
将允许我们克隆一个数据类型,然后通过 GeneralizedNewtypeDeriving
语言自动派生实例扩展(请参阅如何编写衍生类?和处理具有相同内部表示和最小样板的多种类型?)。
问题:是否可以将ghc自动派生 A
和 C
,但要使用我们自己指定的 B
在派生
例如下面的代码(其中 A =
Planet ,
B
= 生活$ c $
$ b $ C
= 说明
) b
{ - #LANGUAGE GeneralizedNewtypeDeriving# - }
{ - #LANGUAGE StandaloneDeriving# - }
module Main(main)where
数据Cat = Cat字符串
newtype Dolphin =海豚猫派生(Planet)
---------------------------- --------------------
class Planet a where
planet :: a - >字符串
类生活在哪里
lives :: a - > String
class(Planet a,Lives a)=>说明a where
description :: a - >字符串
----------------------------------------- -------
实例行星猫其中
planet _ =生活在地球上,
实例猫生活在
的地方_ =生活在陆地上
实例说明Cat where
description a =(planet a)++(lives a)
------ ------------------------------------------
实例生活海豚在哪里
生活_ =生活在海中
- 下面的派生将使用
的实例 - 上面的海豚的生活
导出实例说明Dolphin
---------------------------------- --------------
main = do
print $ description(Cattest)
- > 生活在地球上,生活在陆地上
- OK
print $ description(Dolphin(Cattest))
- > 生活在地球上,生活在土地上
- 不行。想要生活在地球上,生活在海中
我期待/想要的是在 很明显,下面的程序是可行的,但它需要为 p。令人费解的是,如果(在第一个程序中)我没有声明: 然后ghc抱怨: 似乎奇怪ghc会抱怨缺少 考虑以下几点: 这样做是写一个实例,看起来像 换句话说,当您调用 我想象了 问题:如果 (或者这是对你想解决的一些更复杂问题的简化?) Suppose that we have a typeclass QUESTION : Is it possible to get ghc to automatically derive For example the following code (where What I was expecting/wanted was for the Obviously the following program works, but it requires one to explicitly instantiate p.s. What is puzzling is that if (in the first program) I do not declare : Then ghc complains : Seems strange that ghc would complain about the absence of Consider the following: What this does is write an instances that looks like In other words, when you call I imagine the Question: If the definition of (Or is this a simplification of some more complicated problem you want to solve?) 这篇关于通过GeneralizedNewtypeDeriving获取实例时使用自定义实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!的派生中调用
。 生命
的实例>描述
Dolphin明确实例化
:描述
{ - #LANGUAGE GeneralizedNewtypeDeriving# - }
{ - #LANGUAGE StandaloneDeriving# - }
模块Main(main)其中
数据Cat = Cat String
newtype Dolphin = Dolphin Cat派生(Planet)
---- --------------------------------------------
class Planet a where
planet :: a - >字符串
类生活在哪里
lives :: a - > String
class(Planet a,Lives a)=>说明a where
description :: a - >字符串
----------------------------------------- -------
实例行星猫其中
planet _ =生活在地球上,
实例猫生活在
的地方_ =生活在陆地上
实例说明Cat where
description a =(planet a)++(lives a)
------ ------------------------------------------
实例生活海豚在哪里
住_ =住在海中
实例描述海豚其中
描述a =(行星a)++(生命a)
---------------------------------------------- -
main = do
print $ description(Cattest)
- > 生活在地球上,生活在陆地上
- [OK]
print $ description(Dolphin(Cattest))
- > 生活在地球上,生活在海中
- [OK]
instance实例Dolphin where
lives _ =生活在海中
Main.hs:36:1:
实例声明的超类产生的(Lives Dolphin)
的实例
在'Description Dolphin'的实例声明中,$ g $
instance生动Dolphin其中
如果它是不是,在的描述的(自动)派生中使用它
Dolphin
。
$ b
newtype ProcessID = PID Int派生方程式
实例Eq PID其中
(PID x) ==(PID y) = x == y
==
放在 PID
中,它将它解开为一个普通的 Int
,然后执行<$ c
派生实例描述Dolphin
做的完全一样;将 Dolphine
解开为 Cat
,然后调用 description
>方法。这不是你想要的!
description
的定义总是相同的,为什么它需要成为一个班级呢?为什么你不能定义一个正则函数来做到这一点?
class (A a, B a) => C a where
. Using newtype
will allow us to clone a data type and then automatically derive the instances via the GeneralizedNewtypeDeriving
language
extension (See how to write a derivable class? and Handling multiple types with the same internal representation and minimal boilerplate?).A
and C
, but to use our own specified implementation of B
in deriving C
?A
= Planet
, B
= Lives
, C
= Description
) does not work as expected : {-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE StandaloneDeriving #-}
module Main (main) where
data Cat = Cat String
newtype Dolphin = Dolphin Cat deriving (Planet)
------------------------------------------------
class Planet a where
planet :: a -> String
class Lives a where
lives :: a -> String
class (Planet a, Lives a) => Description a where
description :: a -> String
------------------------------------------------
instance Planet Cat where
planet _ = "lives on planet earth,"
instance Lives Cat where
lives _ = "lives on land"
instance Description Cat where
description a = (planet a) ++ (lives a)
------------------------------------------------
instance Lives Dolphin where
lives _ = "lives in the sea"
--want the following derivation to use the instance of
--"Lives" for "Dolphin" above
deriving instance Description Dolphin
------------------------------------------------
main = do
print $ description (Cat "test")
-- > "lives on planet earth,lives on land"
-- OK
print $ description (Dolphin (Cat "test"))
-- > "lives on planet earth,lives on land"
-- NOT OK. Want "lives on planet earth,lives in the sea"
Dolphin
instance of Lives
to be invoked in the derivation of Description
. Description
for Dolphin
:{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE StandaloneDeriving #-}
module Main (main) where
data Cat = Cat String
newtype Dolphin = Dolphin Cat deriving (Planet)
------------------------------------------------
class Planet a where
planet :: a -> String
class Lives a where
lives :: a -> String
class (Planet a, Lives a) => Description a where
description :: a -> String
------------------------------------------------
instance Planet Cat where
planet _ = "lives on planet earth,"
instance Lives Cat where
lives _ = "lives on land"
instance Description Cat where
description a = (planet a) ++ (lives a)
------------------------------------------------
instance Lives Dolphin where
lives _ = "lives in the sea"
instance Description Dolphin where
description a = (planet a) ++ (lives a)
------------------------------------------------
main = do
print $ description (Cat "test")
-- > "lives on planet earth,lives on land"
--[OK]
print $ description (Dolphin (Cat "test"))
-- > "lives on planet earth,lives in the sea"
--[OK]
instance Lives Dolphin where
lives _ = "lives in the sea"
Main.hs:36:1:
No instance for (Lives Dolphin)
arising from the superclasses of an instance declaration
In the instance declaration for ‘Description Dolphin’
instance Lives Dolphin where
if it is not using it in the (automatic) derivation of Description
for Dolphin
.newtype ProcessID = PID Int deriving Eq
instance Eq PID where
(PID x) == (PID y) = x == y
==
on a PID
, it unwraps it into an ordinary Int
, and then executes ==
on that.deriving instance Description Dolphin
is doing exactly the same; unwrapping a Dolphine
into a Cat
, and then calling the description
method on that. Which isn't what you want at all!description
is always the same, why does it need to be a class at all? Why can't you just define a regular function that does this?