SwiftUI View protocol in Haskell

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.