[英]How do Frege classes work?
弗雷格关于类型类的想法似乎与哈斯克尔有很大不同。 特别是:
没有明显的原因,语法似乎有所不同。
函数类型不能具有类实例。 (似乎是一个相当奇怪的规则...)
语言规范说明了有关在子类实例声明中实现超类的内容。 (但是如果您拥有钻石继承权,那不是。。。这不会是一个错误,但是不能保证它能以某种方式起作用吗?)
弗雷格对实例的外观不太挑剔。 (允许使用类型别名,不要求类型变量是唯一的,等等。)
可以将方法声明为native
,尽管尚不清楚其含义是什么。
看来您可以编写type.method
来访问方法。 同样,没有迹象表明这意味着什么或为什么有用。
子类声明可以为超类方法提供默认实现。 (?)
简而言之,如果知道这些东西的人可以写一篇关于这个东西如何工作的解释,将很有用。 它已在语言规范中列出,但说明有些简洁。
(关于语法:我认为Haskell的实例语法更合乎逻辑。“如果X是Y和Z的实例,那么它在以下情况下也是Q的实例...” Haskell的类语法始终看起来有点奇怪对我来说。如果X实现Eq
,并不意味着它实现Ord
,这意味着它可以根据需要实现Ord
。我不确定这是什么更好的符号...)
根据Ingo的回答:
例如,假设Foo
是Bar
的超类。 假设每个类都有三个方法( foo1
, foo2
, foo3
, bar1
, bar2
, bar3
),并且Bar
为foo1
提供了默认实现。 那应该意味着
instance Bar FB where foo2 = ... foo3 = ... bar1 = ... bar2 = ... bar3 = ...
应该管用。 但这会工作:
instance Foo FB where foo2 = ... foo3 = ... instance Bar FB where bar1 = ... bar2 = ... bar3 = ...
native
方法,那么该方法只是设置该方法的默认实现? 所以如果我做类似的事情
class Foobar f where foo :: f -> Int native foo bar :: f -> String native bar
那就意味着如果我为某个Java本机类编写一个空实例声明,那么foo
映射到Java中的object.foo()
?
特别是,如果将类方法声明为native
,那么我仍然可以选择提供其他实现方式?
您似乎已经非常仔细地阅读了语言规范。 大。 但是,没有,类型类/实例与Haskell 2010并没有实质性的区别。只是一点点,而那一点是符号上的。
您的观点:
广告1.是。 规则是约束(如果有)附加到类型上,并且类名紧随关键字之后。 但是,当在语言中添加多参数类型类时,这将很快改变,以支持Haskell语法。
广告2.同时,完全支持功能类型。 这将包含在下一个版本中。 但是,当前版本仅支持(a-> b)。
广告3.是。 考虑我们的分类类层次结构Functor-> Applicative-> Monad。 您只需编写以下内容即可代替3个单独的实例:
instance Monad Foo where
-- implementation of all methods that are due Monad, Applicative, Functor
广告4.是,当前。 但是,多参数类型类将有所变化。 lang规范建议遵循Haskell 2010规则。
广告5.如果您使用类型类对Java类层次结构进行建模,则需要使用该类。 本地函数声明对于类型类/实例没有什么特别的。 因为您可以在类中具有批注和默认实现(就像在Haskell 2010中一样),所以可以以本机声明的形式实现,该声明提供a)类型和b)实现(通过引用a) Java方法)。
广告6。这是正交性。 正如您可以在M为模块的情况下编写M.foo一样,当T为类型(构造函数)时也可以编写T.foo,因为两者都是名称空间。 另外,如果您有“记录”,则在Frege无法推断x
的类型时,可能需要写Tf x
x
。
foo x = x.a + x.b -- this doesn't work, type of x is unknown
-- remedy 1: provide a type signature
foo :: Record -> Int -- Record being some data type
-- remedy 2: access the field getter functions directly
foo x = Record.a x + Record.b x
广告7。是的,例如,就比较而言,Ord的默认实现是(==)。 因此,您可以在不实现(==)的情况下创建Ord实例。
希望这可以帮助。 通常,必须说,lang规范需要a)完成和b)更新。 如果只有一天有36个小时.....
语法问题也在这里讨论: https : //groups.google.com/forum/?fromgroups#!topic/ frege-programming-language/ 2mCNWMVg5eY
- - 第二部分 - - - - - -
您的示例不起作用,因为,如果定义instance Foo FB
则无论其他实例和子类如何,该instance Foo FB
必须成立。 仅当不存在Foo实例时,才会使用Bar中的默认foo1方法。
那就意味着如果我为某个Java本机类编写一个空实例声明,那么foo映射到Java中的object.foo()?
是的,但是它取决于本机声明,它不必是该Java类的Java实例方法,也可以是静态方法或其他类的方法,也可以只是成员访问等。
特别是,如果将类方法声明为本机方法,如果我愿意,我仍然可以为其提供其他实现方式?
当然,就像其他任何默认类方法一样。 假设使用模式防护实现了默认的类方法,但这并不意味着您必须使用模式防护来实现。
看,
native [pure] foo "javaspec" :: a -> b -> c
只是意味着:请给我一个类型为a-> b-> c的frege函数foo
,该函数恰巧使用javaspec进行实现。 (应该在语言参考的第6章中确切描述它。尚未完成。对不起。)例如:
native pure int2long "(long)" :: Int -> Long
编译器将看到这在语法上是强制转换操作,并且会看到:
... int2long val ...
它将生成如下的Java代码:
((long)(unbox(val))
除此之外,它还会包装一个包装,以便您可以例如:
map int2long [1,2,4]
关键是,如果我告诉你:有一个XYz函数,则不查看源代码就无法分辨出它是本地的还是常规的。 因此, native
是将Java方法,运算符等提升到Frege领域的方法。 实际上,在Haskell中称为“ primOp”的所有内容在Frege中只是本机功能。 例如,
pure native + :: Int -> Int -> Int
(当然,这并不总是那么容易。)
每个类型[构造函数]都是一个名称空间。 我知道如何解决臭名昭著的命名字段问题。 我不确定为什么要在此命名空间的范围内声明其他内容...
它使您可以更好地控制顶级名称空间。 除此之外,您不必在那里定义其他内容。 一旦我致力于解决记录领域问题的简单方法,我只是没有理由禁止它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.