I’m no expert in compilers (although, I have an interest in learning in order to improve Crystal).
In my experiments I was attempting to model something and ran into this error which would prevent me from making progress with the particular API that I have in mind.
DOES WORK
abstract struct Errors(T) end
struct Recoverable(T) < Errors(T) end
struct Rand(T)
@errors : Errors(T)
def initialize(@errors) end
end
puts Rand(Int32).new(Recoverable(Int32).new())
DOESN’T WORK (but the Haskell version of this does)
abstract struct Errors(T) end
struct Recoverable(T) < Errors(T) end
struct Rand(T)
@errors : Array(Errors(T))
def initialize(@errors) end
end
puts Rand(Int32).new([Recoverable(Int32).new()])
The Haskell version:
import Data.List
data Errors a = Recoverable a | Bug a deriving Show
data Rand a = Rand {
errors :: [Errors a]
} deriving Show
main = do
print $ Rand $ [Recoverable "You can recover from this error"]
Surrounding code in backticks makes it read easier. Also including the output/playground links can also be helpful.
Carcin Does what you want tho. See Inheritance - Crystal.
1 Like
Hi @JamesGood626 the problem with your example is that in
puts Rand(Int32).new([Recoverable(Int32).new()]
The [Recoverable(Int32).new()]
is of type Array(Recoverable(Int32))
instead of an Array(Errors(Int32))
.
You will need to give the compiler a little hint here. One way is
puts Rand(Int32).new([Recoverable(Int32).new()] of Errors(Int32))
The API of Rand could be changed so you don’t need to do that workaround on callsite. For example
abstract struct Errors(T)
end
struct Recoverable(T) < Errors(T)
end
struct Rand(T)
@errors : Array(Errors(T))
def initialize(errors)
@errors = errors.map { |v| v.as(Errors(T)) }
end
end
puts Rand(Int32).new([Recoverable(Int32).new()])
On missuses the compiler errors would be more cryptic though.
puts Rand(Int32).new([0])
# 11 | @errors = errors.map { |v| v.as(Errors(T)) }
# ^
# Error: can't cast Int32 to Errors(Int32)
Check FAQ · crystal-lang/crystal Wiki · GitHub for some further examples
It’s been awhile, but I wanted to say thank you for your help. Shortly after you posted this I did manage to get it working. I just haven’t been programming much lately.