Open mauro3 opened 7 years ago
I prototyped this in https://github.com/mauro3/SimpleTraits.jl/tree/m3/associated-types, which includes an example:
using SimpleTraits
# This is a trait of one type `Ar` with two associated types `T,N`:
@traitdef LikeArray{T,N}(Ar)
# NOTE: the syntax change: before the types in question where in the curly
# brackets and there where no associated types. Now the type in question is `(Ar)`.
# Sure all Arrays are like arrays:
@traitimpl LikeArray{T,N}(Array{T,N}) where {T,N}
# Note that the trait has the T,N parameters just like Array.
abstract type MAbs end
struct MyType{O,U,N,T} <: MAbs
o::O
u::U
ar::Array{T,N}
end
# Implement array interface...
# add it to trait:
@traitimpl LikeArray{T,N}(MyType{O,U,N,T}) where {O,U,N,T}
# Note how the MyType parameters get mapped onto the associated types
# use it
import Base: eltype, ndims
@traitfn ndims{T,N}(::::LikeArray{T,N}) = (println("Hi"); N)
ndims(MyType(4,5,[3])) # => "Hi" 1
ndims(MyType(4,5,rand(1,1))) # => "Hi" 2
ndims([1]) # => 1 (this does not go via the trait function as normal dispatch
# takes presendce)
@traitfn eltype{T}(::::LikeArray{T}) = T
eltype(MyType(4,5,[3])) # => Int
eltype(MyType(4,5,rand(1,1))) # => Float64
eltype([1]) # => Int
@traitfn two_dim_only{T}(::::LikeArray{T,2}) = "I have ndim==2"
@traitfn two_dim_only{T}(::::(!LikeArray{T,2})) = "I have ndim!=2"
two_dim_only(rand(2,2)) # => "I have ndim==2"
# this sadly doesn't work, needs some more thoughs:
two_dim_only(MyType(4,5,[3])) # => error
This is essentially the {T}
in what Keno requested here (but of course without the bit which allows to specify the trait in terms of implemented interface).
I think this is pretty sweet. Is there any use for this for people who actually use SimpleTraits? CC: @timholy, @sbromberger, @ChrisRackauckas, @davidanthoff, @JeffreySarnoff (sorry about the indiscriminate CCing, I got a bit excited!)
Thanks for asking. This feels like a step that brings not-yet-builtin traits closer to their Julian realization.
Sorry for the delayed response. I'm still trying to wrap my head around this proposal :)
No worries, no need for quick response. In a nutshell it would allow for traits to have parameters just like abstract types, where things like T,N
in AbstractArray{T,N}
can be useful for dispatch.
Would be interesting to discuss/hack this at JuliaCon 2018, if anyone is interested.
I like parameters.
The
AbstractArray
interface also encompasses the meaning of the type parameters:MyArray{T,N}
has eltypeT
and dimN
. A traitLikeArray
ought to contain these two type parameters also, which in this context are associated types (at least Rust uses this term). Maybe this could be written asTraitAbstractArray{TT,2}(SomeTypeWhichIsAlsoArrayLike{P1,P2,TT})
, which would mean thatSomeTypeWhichIsAlsoArrayLike{P1,P2,T}
belongs to the trait and that it has associated typeseltype==TT
andndims==2
. Note this syntax is different to the current syntax on master, where the type-parameters are occupied by the types fulfilling (or not) the trait.Not sure this is SimpleTraits material but I thought I better write it down somewhere before I forget.