I am trying to implement a Haskell counterpart of the View
protocol of SwiftUI using type class and type family.
The View
protocol in SwiftUI is something like:
protocol View {
associatedtype Body: View
var body: Body { get }
}
Through type class and the associated type family, I can have:
{-# LANGUAGE TypeFamilies, AllowAmbiguousTypes, FlexibleContexts, U
ndecidableSuperClasses #-}
class (View (Body x)) => View x where
type Body x
body :: Body x
which fails to compile: solveWanteds: too many iterations (limit = 4)
.
My question is if there is a way to achieve such ‘recursive’ type class definition in Haskell?
The problem doesn’t seem to be recursive definition
, although the errors make it out to be like that.
Rather, it is this part:
body :: Body x
The function is considered as body :: View x => Body x
. Compiler cannot infer x
even with desired result type Body x
, since you cannot know x
from Body x
. For instance, you might have Body Foo = Int
, Body Bar = Int
and you have no way of knowing if x
should be Foo
or Bar
.
instead, I think what you should have is this:
class (View (Body x)) => View x where
type Body x
body :: x -> Body x
It seems like Swift protocol assumes this
instance. In haskell, typeclasses does not have this
or anything referring to the self instance. So, you need to provide it yourself.
2 Likes
Thank you for your reply! This makes a lot of sense to me.