繁体   English   中英

Frege课程如何运作?

[英]How do Frege classes work?

弗雷格关于类型类的想法似乎与哈斯克尔有很大不同。 特别是:

  • 没有明显的原因,语法似乎有所不同。

  • 函数类型不能具有类实例。 (似乎是一个相当奇怪的规则...)

  • 语言规范说明了有关在子类实例声明中实现超类的内容。 (但是如果您拥有钻石继承权,那不是。。。这不会是一个错误,但是不能保证它能以某种方式起作用吗?)

  • 弗雷格对实例的外观不太挑剔。 (允许使用类型别名,不要求类型变量是唯一的,等等。)

  • 可以将方法声明为native ,尽管尚不清楚其含义是什么。

  • 看来您可以编写type.method来访问方法。 同样,没有迹象表明这意味着什么或为什么有用。

  • 子类声明可以为超类方法提供默认实现。 (?)

简而言之,如果知道这些东西的人可以写一篇关于这个东西如何工作的解释,将很有用。 它已在语言规范中列出,但说明有些简洁。

(关于语法:我认为Haskell的实例语法更合乎逻辑。“如果X是Y和Z的实例,那么它在以下情况下也是Q的实例...” Haskell的类语法始终看起来有点奇怪对我来说。如果X实现Eq ,并不意味着它实现Ord ,这意味着它可以根据需要实现Ord 。我不确定这是什么更好的符号...)


根据Ingo的回答:

  • 我假设为超类方法提供默认实现仅在您声明实例“一次”的情况下有效吗?

例如,假设FooBar的超类。 假设每个类都有三个方法( foo1foo2foo3bar1bar2bar3 ),并且Barfoo1提供了默认实现。 那应该意味着

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM