1

Was looking at some problems to improve my knwoledge on foldable and functors but cannot quite seem to get my head around how to create the toList function using foldable and a functor

This is what i have so far was unsure if i would need to create my own instance for foldable here

I want to create toList explicitly using the type definition below

instance Foldable [] where 
  fold = undefined

toList :: (Functor c, Foldable c) => c a -> [a]
toList f = undefined

Any help and explanation to what i have to do is appreciated

duplode
  • 33,731
  • 7
  • 79
  • 150
  • perhaps use a closure? – jspcal Oct 21 '21 at 21:07
  • @jspcal i do not know what a closure is sorry can you explain – what a day to b aliive Oct 21 '21 at 21:16
  • @jspcal, that hardly seems relevant or helpful. – dfeuer Oct 21 '21 at 22:19
  • @whatadaytobaliive, closures are data structures used in some implementations of some programming languages, especially ones offering first class functions and/or non-strict evaluation. I have no idea what they might have to do with your question. – dfeuer Oct 21 '21 at 22:22
  • 1
    A more interesting/appropriate problem, but a somewhat tricky one: write `toList :: Traversable f => f a -> [a]` using only the `traverse` method of `Traversable`. Bonus: test that `take 10 . toList $ [1..] = [1..10]`. – dfeuer Oct 21 '21 at 22:38
  • @dfeuer that was a nice one. it even holds that `catMaybes = t_toList . magic`, for a particular `magic` word. – Will Ness Oct 25 '21 at 04:33
  • @WillNess, yes, that's true. The point of my "bonus" was to check laziness. I'm not sure what the reimplementation of `catMatbes` is for, but I know what `magic` is. It relates to a certain type known for its `Functor`, `Applicative`, and `Traversable` instances. (Why are you keeping it secret?) – dfeuer Oct 25 '21 at 05:16
  • 1
    @dfeuer was just following in your footsteps, so an interested reader would have the chance to figure it out for themself. it's not "for" anything, I just tested it on some type other than list, and saw it working that way. couldn't tell in advance what it would do, stop on a first Nothing, or what. – Will Ness Oct 25 '21 at 07:33
  • @WillNess, just think about how folding that magical thing works. – dfeuer Oct 25 '21 at 07:50
  • @dfeuer I will have to work through it closely, step by step... – Will Ness Oct 25 '21 at 08:11

1 Answers1

3

To write toList, you actually only need the Foldable constraint. In fact, you only need foldr. The key insight is the following law. When xs is a list,

foldr (:) [] xs = xs

But the type of foldr (:) [] is

Foldable t => t a -> [a]

which means it turns any Foldable into a list. And sure enough, this is an acceptable definition of toList:

toList :: Foldable t => t a -> [a]
toList = foldr (:) []
Rein Henrichs
  • 15,437
  • 1
  • 45
  • 55
  • thanks for the answer i know you only need the foldable constraint i seen some stuff online about that but i wanted to see if you can do it using a functor to how would you do it with a functor to? I wanted to try create it using the type def i have been given do you have any ideas how to go about such – what a day to b aliive Oct 21 '21 at 21:48
  • 3
    You can't. A functor says "I have a thing shaped like X, give me a thing shaped like X with different contents". Foldable says "I have a thing shaped like X, I'm going to reduce it to some other thing shaped like Y". You can't change the shape with a functor. – Silvio Mayolo Oct 21 '21 at 21:54
  • @SilvioMayolo so u cant do it with both a functor and foldable in the definition i mean using both not just functor on its own – what a day to b aliive Oct 21 '21 at 21:57
  • 2
    Well, sure, I guess. But why would you include constraints you're not going to use? I could also require that the type be `Monad`, `Arrow`, `Monoid`, `Alternative`, and `Profunctor`, but what's the sense in requiring typeclasses I'm not going to use? – Silvio Mayolo Oct 21 '21 at 22:00
  • @SilvioMayolo i am including these certain constraints to try develop my knowledge and practical skills in usimg foldable and functor thats why? So thats why i am looking for help to solve this specific way – what a day to b aliive Oct 21 '21 at 22:05
  • 2
    @whatadaytobaliive, there's nothing the `Functor` class has to offer that would be *helpful* for solving this problem. The type might happen to be an instance of `Functor`, but that's irrelevant; you don't need to require that. Most of the time, you want your functions to have as *few* class constraints as practical. (There are special situations where this is not the case, but that's pretty advanced stuff.) – dfeuer Oct 21 '21 at 22:28
  • `Functor` only provides one thing: `fmap :: (a -> b) -> f a -> f b`. Note that you can't use `fmap` to change the type `f`. In other words, there is no way to write `toList :: (Functor t) => t a -> [a]`, because `fmap` _cannot_ change `t` into `[]` — no matter what it does. – Rein Henrichs Oct 21 '21 at 23:37