Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is (a,b,c,d) not sugar for (a,(b,(c,(d,()))))?

Tags:

types

haskell

It's clear that any n-tuple can be represented by a bunch of nested 2-tuples. So why are they not the same thing in Haskell? Would this break something?

Making these types equivalent would make writing functions on tuples much easier. For example, instead of defining zip,zip2,zip3,etc., you could define only a single zip function that would work for all tuples.

Of course, you can work with nested 2-tuples, but it is ugly and there is no canonical way to perform the nesting (i.e. should we nest to the left or right?).

like image 967
Mike Izbicki Avatar asked Feb 20 '13 06:02

Mike Izbicki


People also ask

Why is sugar alcohol not designated D or L?

1. In the monosaccharide derivatives known as sugar alcohols, the carbonyl oxygen is reduced to a hydroxyl group. For example, D-glyceraldehyde can be reduced to glycerol. However, this sugar alcohol is no longer designated D or L.

What does D mean in sugars?

D-glucose occurs more abundantly in nature than L-glucose. D-glucose is a short form of dextrorotatory glucose. It is one of the two stereoisomers of glucose, and is the one that is biologically active. It occurs in plants as a product of photosynthesis.

Can dextrose be labeled as sugar?

Sugar is called by many namesIngredients listed on the food label that end in “ose” are forms of sugar, such as fructose, sucrose, maltose and dextrose. Others can include the following: Brown sugar. Confectioners powdered sugar.

What are the 3 sugars?

Glucose, fructose and galactose are the three monosaccharides important in nutrition.


2 Answers

The type (a,b,c,d) has a different performance profile from (a,(b,(c,(d,())))). In general, indexing into an n-tuple takes O(1) while indexing into an "hlist" of n nested tuples takes O(n).

That said, you should check out Oleg's classic work on HLists. Using HLists requires extensive, and somewhat sketchy, use of type level programming. Many people find this unacceptable, and it was not available in early Haskell. Probably the best way to represent an HList today is with GADTs and DataKinds

data HList ls where   Nil  :: HList '[]   Cons :: x -> HList xs -> HList (x ': xs) 

This give canonical nesting, and lets you write functions that work for all instances of this type. You could implement your multi way zipWith using the same techniques as used in printf. A more interesting puzzle is to generate the appropriate lenses for this type (hint: use type level naturals and type families for indexing in).

I have considered writing an HList like library that used arrays and unsafeCoerce under the hood to get tuple like performance while sticking to a generic interface. I haven't done it, but it should not be overly difficult.

EDIT: the more I think about this the more inclined I am to hack something together when I have the time. The repeated copying problem Andreas Rossberg mentions can probably be eliminated using stream fusion or similar techniques.

like image 148
Philip JF Avatar answered Sep 22 '22 05:09

Philip JF


The main problem with this in Haskell would be that a nested tuple allows additional values, due to laziness. For example, the type (a,(b,()) is inhabited by all (x,_|_) or (x,(y,_|_)), which is not the case for flat tuples. The existence of these values is not only semantically inconvenient, it also would make tuples much more difficult to optimise.

In a strict language, though, your suggestion is indeed a possibility. But it still introduces a performance pitfall: implementations would still want to flatten tuples. Consequently, in the cases where you actually construct or deconstruct them inductively, they would have to do a lot of repeated copying. When you use really large tuples, that might be a problem.

like image 44
Andreas Rossberg Avatar answered Sep 24 '22 05:09

Andreas Rossberg