Trait-based dispatch 与 typeclass 有何异同?

一直不太清楚SimpleTraits.jl的用法,好像跟typeclass的功能有点像:

julia> using SimpleTraits

julia> @traitdef Tr{Array}

julia> @traitfn fn(x::X) where {X<:Vector; Tr{X}} = 4
fn (generic function with 2 methods)

julia> @traitimpl Tr{Vector{Int}}

julia> fn([1,2,3])
4

julia> fn([1.0,2.0,3.0])
ERROR: MethodError: no method matching fn(::Type{Not{Tr{Array{Float64,1}}}}, ::Array{Float64,1})
Closest candidates are:
  fn(::Type{Tr{X<:(Array{T,1} where T)}}, ::X<:(Array{T,1} where T)) where X<:(Array{T,1} where T) at /Users/gnimuc/.julia/packages/SimpleTraits/CZOA2/src/SimpleTraits.jl:332
Stacktrace:
 [1] fn(::Array{Float64,1}) at /Users/gnimuc/.julia/packages/SimpleTraits/CZOA2/src/SimpleTraits.jl:350
 [2] top-level scope at none:0

还有trait这个术语一般表示什么意思?

trait是指类型的一些信息吧?比如

name(::{<:Me}) = "Roger"

不太严格的来说,应该都是polymorphism加上类型上constraints。trait这个词现在已经各种乱用了,一般用来指满足一些性质的类型吧。不过,Haskell貌似typeclass声明里面里面不能像这样直接绑定值的,Scala里面我倒是能写出来差不多的。

3 个赞

Trait 这个概念最早来自 SELF 语言,是一种基于 prototype 的 OO 语言。

Trait 只包含行为,把某一类相关的行为封装在一起。后来很多语言都引入了这个概念……

1 个赞

Julia里更加常用的是Holy Trait(name after Tim Holy)。SimpleTraits更多感觉是POC的一个实验。

Holy Trait大概是这样一种设计模式+Trait

abstract type SomePropertyTrait end
struct PropertyOne <: SomePropertyTrait end
struct PropertyTwo <: SomePropertyTrait end
struct Unkown <: SomePropertyTrait end


SomePropertyTrait(x::T1) = PropertyOne()
foo(x::T1, args...) =  foo(SomePropertyTrait(x), x, args...)
foo(::PropertyOne, x, args...) = blabla

利用Holy Trait可以做到类似混入(mixin)的东西,或者说是多继承。然后这里是利用了pure function会被编译器优化掉的特点。

1 个赞

就两者的完全体来说,trait = type class…