Cool to see Representable used on a non-trivial example. One way of thinking about Representable is that the index type is like a logarithm of your data type (if you visualize the function type i->a as an exponential a^i). Three and Grid are both product types, and you can always take a logarithm of a product--you get a sum. As you mentioned, list is not representable because it's a sum type: List a = 1 + a * List a. An infinite list, on the other hand, is an infinite product, so it's representable.
Great video as usual! I have a question regarding performance overhead: can GHC optimize away the Distributive/Representable for Grid and obtain something similar to the initial hand written code? I initially thought yes because all the functions involved are non-recursive, but then realized that the indices IxThree exist at run-time representations and GHC will not be clever enought to optimize it way.
Why don't you use tabulate to define positions, so you don't need that Applicative instance? positions grid = tabulate $ \i -> (index grid i, setter i grid)
Cool to see Representable used on a non-trivial example. One way of thinking about Representable is that the index type is like a logarithm of your data type (if you visualize the function type i->a as an exponential a^i). Three and Grid are both product types, and you can always take a logarithm of a product--you get a sum. As you mentioned, list is not representable because it's a sum type: List a = 1 + a * List a. An infinite list, on the other hand, is an infinite product, so it's representable.
Great video as usual! I have a question regarding performance overhead: can GHC optimize away the Distributive/Representable for Grid and obtain something similar to the initial hand written code? I initially thought yes because all the functions involved are non-recursive, but then realized that the indices IxThree exist at run-time representations and GHC will not be clever enought to optimize it way.
Why don't you use tabulate to define positions, so you don't need that Applicative instance?
positions grid = tabulate $ \i -> (index grid i, setter i grid)
Yes, that would have been simpler.