[Haskell-beginners] Return a Foldable instance

Federico Mastellone fmaste at gmail.com
Wed May 4 08:04:11 CEST 2011


Thanks for the tip about ExistentialQuantification! I'll take a look at it.

On Wed, May 4, 2011 at 2:06 AM, Alexander Dunlap
<alexander.dunlap at gmail.com> wrote:
> This probably isn't a good solution to your problem, but you could use
> an existential type to hide what the type actually was. You need a GHC
> extension (ExistentialQuantification, I think) for this to work. The
> following code is completely untested and the syntax might be wrong,
> but the idea should be right:
>
> data SomethingFoldable = SomethingFoldable (forall f. Foldable f => f)
>
> Now your function can return a value of type SomethingFoldable. Notice
> that the type of SomethingFoldable is not parameterized by the type of
> f: the "forall" keyword inside the parentheses means that the value
> could be *any* type that satisfies the Foldable constraint.
>
> Note that this hugely limits what the caller can do with the value.
> They don't know what type the value is, so they can't use list
> functions (because the value might be a Set or something else
> Foldable) or Set functions (because the value might be a list or
> something else Foldable). All they know is that the value is a member
> of the Foldable class, so the only way the value can be used is in a
> function that takes an arbitrary member of the Foldable class as a
> value. (function :: Foldable f => ... -> f -> ...)
>
> Because of this, I've found that this technique's usefulness is
> limited to situations where you really want to be leveraging the type
> system to do something interesting. In other cases, there is probably
> just one function (since type classes generally don't have a lot of
> member functions) that your caller would be applying to the returned
> value, and you could just call that function within your function and
> return the result of that. (You might have to add additional arguments
> to your function, like a function to fold with or an initial value,
> etc.)
>
> Hope that helps you a bit.
>
> Alex
>
> On 3 May 2011 21:08, Federico Mastellone <fmaste at gmail.com> wrote:
>> Thank you both!
>>
>> So, how can I return something that implements Foldable, so the caller
>> can fold without knowing if it is a [] or a Set and also be able to
>> change the underlying implementation without breaking the code?
>>
>> With this I also want to avoid the extra overhead of the conversion to
>> or from lists, so the user will be folding the [] or Set directly,
>> depending on the implementation.
>>
>> Creating an intermediate data type like this:
>> Temp a = TempList [a] | TempSet (Set a) | ...
>> That implements Foldable could be one solution, but is it a good one?
>> A cons of this is that every new implementation will have to alter
>> this type as well as creating the implementation.
>>
>> Thanks again!
>>
>> On Wed, May 4, 2011 at 12:27 AM, Antoine Latter <aslatter at gmail.com> wrote:
>>> On Tue, May 3, 2011 at 8:31 PM, Federico Mastellone <fmaste at gmail.com> wrote:
>>>> Hi,
>>>>
>>>> I want to make a function that returns a Foldable instance, briefly,
>>>> something like this:
>>>>
>>>> import Data.Foldable
>>>>
>>>> test :: Foldable f => f Int
>>>> test = [1,2,3,4]
>>>>
>>>
>>> One point that helped me figure things out:
>>>
>>> The signature:
>>>
>>>> test :: Foldable f => f Int
>>>
>>> does NOT mean "the value test satisfies the 'Foldable' contract'
>>>
>>> It means "the value test is of ANY 'Foldable' type". As in, it is of
>>> whatever type the caller picks, so long as it is 'Foldable'. And a
>>> list is not 'whatever type the caller picks.'
>>>
>>> Type classes are used in Haskell to write polymorphic functions, not
>>> for implementation hiding:
>>>
>>>> myNumericalCalculation :: Fractional n => n -> n -> Bool -> n
>>>
>>> The caller can pick if they want to use limited precision Floats or
>>> Doubles, or if they want to pay the price for infinite precision Ratio
>>> types, or some type that I hadn't even thought of when I wrote the
>>> functions.
>>>
>>> Antoine
>>>
>>>> But I get this error:
>>>>
>>>>    Couldn't match expected type `f' against inferred type `[]'
>>>>        `f' is a rigid type variable bound by
>>>>            the type signature for `test' at Test.hs:3:17
>>>>    In the expression: [1, 2, 3, 4]
>>>>    In the definition of `test': test = [1, 2, 3, ....]
>>>>
>>>> How can I make a function like the one above?
>>>>
>>>> I'm creating different implementations of a multimap, using a Set and
>>>> a [], and instead of providing functions getValuesList and
>>>> getValuesSet that return a [] and a Set respectively I want to provide
>>>> a more generic one, getValues that returns a Foldable instance.
>>>>
>>>> Thanks!!!
>>>>
>>>> --
>>>> Federico Mastellone
>>>> Computer Science Engineer - ITBA
>>>> ".. there are two ways of constructing a software design: One way is
>>>> to make it so simple that there are obviously no deficiencies, and the
>>>> other way is to make it so complicated that there are no obvious
>>>> deficiencies. The first method is far more difficult."
>>>>
>>>> Tony Hoare, 1980 ACM Turing Award Lecture.
>>>>
>>>> _______________________________________________
>>>> Beginners mailing list
>>>> Beginners at haskell.org
>>>> http://www.haskell.org/mailman/listinfo/beginners
>>>>
>>>
>>
>>
>>
>> --
>> Federico Mastellone
>> Computer Science Engineer - ITBA
>> ".. there are two ways of constructing a software design: One way is
>> to make it so simple that there are obviously no deficiencies, and the
>> other way is to make it so complicated that there are no obvious
>> deficiencies. The first method is far more difficult."
>>
>> Tony Hoare, 1980 ACM Turing Award Lecture.
>>
>> _______________________________________________
>> Beginners mailing list
>> Beginners at haskell.org
>> http://www.haskell.org/mailman/listinfo/beginners
>>
>



-- 
Federico Mastellone
Computer Science Engineer - ITBA
".. there are two ways of constructing a software design: One way is
to make it so simple that there are obviously no deficiencies, and the
other way is to make it so complicated that there are no obvious
deficiencies. The first method is far more difficult."

Tony Hoare, 1980 ACM Turing Award Lecture.



More information about the Beginners mailing list