弗雷格课程如何运作?

Mat*_*hid 7 types functional-programming class frege

似乎Frege关于类型类的想法与Haskell有很大不同.特别是:

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

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

  • 语言规范说明了在子类实例声明中实现超类.(但如果你有钻石继承,那就不行了......这不会是一个错误,但它不能保证以某种方式工作?)

  • 弗雷格对实例的看法不那么挑剔.(允许输入别名,类型变量不需要是不同的,等等)

  • 方法可以声明为native,虽然还不完全清楚这是什么意思.

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

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

简而言之,如果知道这些东西的人可以写出这些东西如何工作的解释将是有用的.它在语言规范中列出,但描述有点简洁.

(关于语法:我认为Haskell的实例语法更合乎逻辑."如果X是Y和Z的实例,那么它也是以下列方式的Q实例......"Haskell的类语法总是看起来有点奇怪对我来说.如果X实现Eq,这并不意味着它实现Ord,它暗示它可以实现,Ord如果它想要.我不知道什么是更好的符号将...)


Per 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映射到object.foo()Java?

特别是,如果一个类方法被声明为native,如果我选择,我仍然可以为它提供一些其他实现?

  • 每个类型[构造函数]都是一个名称空间.我知道这对臭名昭着的命名字段问题会有什么帮助.我不确定你为什么要在这个命名空间的范围内声明其他东西......

Ing*_*ngo 6

您似乎非常仔细地阅读了语言规范.大.但是,不,类型类/实例与Haskell 2010没有实质性差别.只是一点点,这一点是符号.

你的观点:

广告1.是的.规则是约束(如果有)附加到类型,类名跟在关键字之后.但是,当将多个param类型类添加到语言中时,这将很快改变,以支持Haskell语法.

同时,完全支持功能类型.这将包含在下一个版本中.但是,当前版本仅支持(a-> b).

广告3.是的.考虑我们的分类类层次结构Functor - > Applicative - > Monad.您可以编写以下内容而不是3个单独的实例:

instance Monad Foo where
    -- implementation of all methods that are due Monad, Applicative, Functor
Run Code Online (Sandbox Code Playgroud)

广告4.是的,目前.但是,多参数类型类会有变化.lang规范建议遵守Haskell 2010规则.

如果您使用类型类对Java类层次结构进行建模,则需要使用它.本机函数声明对类型类/实例没什么特别之处.因为您可以在类中具有注释和默认实现(就像在Haskell 2010中一样),您可以以本机声明的形式获得它,其中a)类型和b)实现(通过引用Java方法).

ad 6.这是正交性的.正如您可以编写M.foo,其中M是一个模块,当T是一个类型(构造函数)时,您可以编写T.foo,因为它们都是名称空间.另外,如果你有一个"记录",你可能需要T.f 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
Run Code Online (Sandbox Code Playgroud)

ad 7.是的,例如,Ord在比较方面有(==)的默认实现.因此,您可以在不实现(==)的情况下创建某个Ord实例.

希望这可以帮助.通常,必须说,lang规范需要a)完成和b)更新.如果只有一天有36个小时.....

这里还讨论了语法问题:https://groups.google.com/forum/?fromgroups#!topic / lost-programming-language/ 2mCNWMVg5eY

- - 第二部分 - - - - - -

您的示例不起作用,因为,如果您定义,instance Foo FB那么必须保持,不管其他实例和子类.仅当不存在Foo实例时,才会使用Bar中的默认foo1方法.

那么这只意味着如果我为某个Java本机类编写一个空实例声明,那么foo映射到Java中的object.foo()?

是的,但它取决于本机声明,它不一定是该java类的Java实例方法,它也可以是静态方法或另一个类的方法,或者只是成员访问等.

特别是,如果一个类方法被声明为native,我仍然可以为它提供一些其他实现,如果我选择的话?

当然,就像使用任何其他默认类方法一样.假设使用模式保护实现默认类方法,这并不意味着您必须使用模式保护来实现.

看,

native [pure] foo "javaspec" :: a -> b -> c
Run Code Online (Sandbox Code Playgroud)

只是意味着:请让我成为一个foo类型为a - > b - > c 的frege函数,恰好使用javaspec实现.(在语言参考的第6章中应该如何描述.它还没有完成.抱歉.)例如:

native pure int2long "(long)" :: Int -> Long
Run Code Online (Sandbox Code Playgroud)

编译器会看到这在语法上是一个强制转换操作,当它看到时:

 ... int2long val ... 
Run Code Online (Sandbox Code Playgroud)

它将生成如下代码:

((long)(unbox(val))
Run Code Online (Sandbox Code Playgroud)

除此之外,它还将制作一个包装器,以便您可以,例如:

map int2long [1,2,4]
Run Code Online (Sandbox Code Playgroud)

关键是,如果我告诉你:有一个函数XYz,你无法在不查看源代码的情况下判断这是一个原生的还是常规的.因此,native是将Java方法,运算符等提升到Frege领域的方法.实际上,Haskell中所谓的"primOp"只是Frege中的一个本机函数.例如,

pure native + :: Int -> Int -> Int
Run Code Online (Sandbox Code Playgroud)

(当然,这并不总是那么容易.)

每个类型[构造函数]都是一个名称空间.我知道这对臭名昭着的命名字段问题会有什么帮助.我不确定你为什么要在这个命名空间的范围内声明其他东西......

它为您提供了有关顶级命名空间的更多控制权.除此之外,您不必在那里定义其他东西.一旦我致力于解决记录领域问题的这种简单方法,我就没有理由禁止它.