https://wiki.haskell.org/api.php?action=feedcontributions&user=Shahn&feedformat=atomHaskellWiki - User contributions [en]2022-10-02T00:43:58ZUser contributionsMediaWiki 1.31.7https://wiki.haskell.org/index.php?title=GHC/Type_families&diff=59631GHC/Type families2015-04-04T11:12:30Z<p>Shahn: /* Injectivity, type inference, and ambiguity */ formatting</p>
<hr />
<div>Indexed type families, or '''type families''' for short, are a Haskell extension supporting ad-hoc overloading of data types. Type families are parametric types that can be assigned specialized representations based on the type parameters they are instantiated with. They are the data type analogue of [[Type class|type classes]]: families are used to define overloaded ''data'' in the same way that classes are used to define overloaded ''functions''. Type families are useful for generic programming, for creating highly parameterised library interfaces, and for creating interfaces with enhanced static information, much like dependent types.<br />
<br />
Type families come in two flavors: ''data families'' and ''type synonym families''. Data families are the indexed form of data and newtype definitions. Type synonym families are the indexed form of type synonyms. Each of these flavors can be defined in a standalone manner or ''associated'' with a type class. Standalone definitions are more general, while associated types can more clearly express how a type is used and lead to better error messages.<br />
<br />
''NB: see also Simon's [http://hackage.haskell.org/trac/ghc/blog/LetGeneralisationInGhc7 blog entry on let generalisation] for a significant change in the policy for let generalisation, driven by the type family extension. In brief: a few programs will puzzlingly fail to compile with <tt>-XTypeFamilies</tt> even though the code is legal Haskell 98.''<br />
<br />
== What are type families? ==<br />
<br />
The concept of a type family comes from type theory. An indexed type family in type theory is a partial function at the type level. Applying the function to parameters (called ''type indices'') yields a type. Type families permit a program to compute what data constructors it will operate on, rather than having them fixed statically (as with simple type systems) or treated as opaque unknowns (as with parametrically polymorphic types).<br />
<br />
Type families are to vanilla data types what type class methods are to regular functions. Vanilla polymorphic data types and functions have a single definition, which is used at all type instances. Classes and type families, on the other hand, have an interface definition and any number of instance definitions. A type family's interface definition declares its [[kind]] and its arity, or the number of type indices it takes. Instance definitions define the type family over some part of the domain.<br />
<br />
As a simple example of how type families differ from ordinary parametric data types, consider a strict list type. We can represent a list of <hask>Char</hask> in the usual way, with cons cells. We can do the same thing to represent a list of <hask>()</hask>, but since a strict <hask>()</hask> value carries no useful information, it would be more efficient to just store the length of the list. This can't be done with an ordinary parametric data type, because the data constructors used to represent the list would depend on the list's type parameter: if it's <hask>Char</hask> then the list consists of cons cells; if it's <hask>()</hask>, then the list consists of a single integer. We basically want to select between two different data types based on a type parameter. Using type families, this list type could be declared as follows:<br />
<br />
<haskell><br />
-- Declare a list-like data family<br />
data family XList a<br />
<br />
-- Declare a list-like instance for Char<br />
data instance XList Char = XCons !Char !(XList Char) | XNil<br />
<br />
-- Declare a number-like instance for ()<br />
data instance XList () = XListUnit !Int<br />
</haskell><br />
<br />
The right-hand sides of the two <code>data instance</code> declarations are exactly ordinary data definitions. In fact, a <code>data instance</code> declaration is nothing more than a shorthand for a <code>data</code> declaration followed by a <code>type instance</code> (see below) declaration. However, they define two instances of the same parametric data type, <hask>XList Char</hask> and <hask>XList ()</hask>, whereas ordinary data declarations define completely unrelated types. A recent [[Simonpj/Talk:FunWithTypeFuns|tutorial paper]] has more in-depth examples of programming with type families. <br />
<br />
[[GADT]]s bear some similarity to type families, in the sense that they allow a parametric type's constructors to depend on the type's parameters. However, all GADT constructors must be defined in one place, whereas type families can be extended. Functional dependencies are similar to type families, and many type classes that use functional dependencies can be equivalently expressed with type families. Type families provide a more functional style of type-level programming than the relational style of functional dependencies.<br />
<br />
== What do I need to use type families? ==<br />
<br />
Type families are a GHC extension enabled with the <code>-XTypeFamilies</code> flag or the <code>{-# LANGUAGE TypeFamilies #-}</code> pragma. The first stable release of GHC that properly supports type families is 6.10.1. (The 6.8 release included an early partial implementation, but its use is deprecated.) Please [http://hackage.haskell.org/trac/ghc/query?status=new&status=assigned&status=reopened&group=priority&type=bug&order=id&desc=1 report bugs] via the GHC bug tracker, ideally accompanied by a small example program that demonstrates the problem. Use the [mailto:glasgow-haskell-users@haskell.org GHC mailing list] for questions or for a discussion of this language extension and its description on this wiki page.<br />
<br />
== An associated data type example ==<br />
<br />
As an example, consider Ralf Hinze's [http://www.cs.ox.ac.uk/ralf.hinze/publications/GGTries.ps.gz generalised tries], a form of generic finite maps. <br />
<br />
=== The class declaration ===<br />
<br />
We define a type class whose instances are the types that we can use as keys in our generic maps:<br />
<haskell><br />
class GMapKey k where<br />
data GMap k :: * -> *<br />
empty :: GMap k v<br />
lookup :: k -> GMap k v -> Maybe v<br />
insert :: k -> v -> GMap k v -> GMap k v<br />
</haskell><br />
The interesting part is the ''associated data family'' declaration of the class. It gives a [http://www.haskell.org/ghc/docs/latest/html/users_guide/type-families.html#data-family-declarations ''kind signature''] (here <hask>* -> *</hask>) for the associated data type <hask>GMap k</hask> - analogous to how methods receive a type signature in a class declaration.<br />
<br />
What it is important to notice is that the first parameter of the associated type <hask>GMap</hask> coincides with the class parameter of <hask>GMapKey</hask>. This indicates that also in all instances of the class, the instances of the associated data type need to have their first argument match up with the instance type. In general, the type arguments of an associated type can be a subset of the class parameters (in a multi-parameter type class) and they can appear in any order, possibly in an order other than in the class head. The latter can be useful if the associated data type is partially applied in some contexts.<br />
<br />
The second important point is that as <hask>GMap k</hask> has kind <hask>* -> *</hask> and <hask>k</hask> (implicitly) has kind <hask>*</hask>, the type constructor <hask>GMap</hask> (without an argument) has kind <hask>* -> * -> *</hask>. Consequently, we see that <hask>GMap</hask> is applied to two arguments in the signatures of the methods <hask>empty</hask>, <hask>lookup</hask>, and <hask>insert</hask>.<br />
<br />
=== An Int instance ===<br />
<br />
To use Ints as keys into generic maps, we declare an instance that simply uses <hask>Data.IntMap</hask>, thusly:<br />
<haskell><br />
instance GMapKey Int where<br />
data GMap Int v = GMapInt (Data.IntMap.IntMap v)<br />
empty = GMapInt Data.IntMap.empty<br />
lookup k (GMapInt m) = Data.IntMap.lookup k m<br />
insert k v (GMapInt m) = GMapInt (Data.IntMap.insert k v m)<br />
</haskell><br />
The <hask>Int</hask> instance of the associated data type <hask>GMap</hask> needs to have both of its parameters, but as only the first one corresponds to a class parameter, the second needs to be a type variable (here <hask>v</hask>). As mentioned before, any associated type parameter that corresponds to a class parameter must be identical to the class parameter in each instance. The right hand side of the associated data declaration is like that of any other data type.<br />
<br />
NB: At the moment, GADT syntax is not allowed for associated data types (or other indexed types). This is not a fundamental limitation, but just a shortcoming of the current implementation, which we expect to lift in the future.<br />
<br />
As an exercise, implement an instance for <hask>Char</hask> that maps back to the <hask>Int</hask> instance using the conversion functions <hask>Char.ord</hask> and <hask>Char.chr</hask>.<br />
<br />
=== A unit instance ===<br />
<br />
Generic definitions, apart from elementary types, typically cover units, products, and sums. We start here with the unit instance for <hask>GMap</hask>:<br />
<haskell><br />
instance GMapKey () where<br />
data GMap () v = GMapUnit (Maybe v)<br />
empty = GMapUnit Nothing<br />
lookup () (GMapUnit v) = v<br />
insert () v (GMapUnit _) = GMapUnit $ Just v<br />
</haskell><br />
For unit, the map is just a <hask>Maybe</hask> value.<br />
<br />
=== Product and sum instances ===<br />
<br />
Next, let us define the instances for pairs and sums (i.e., <hask>Either</hask>):<br />
<haskell><br />
instance (GMapKey a, GMapKey b) => GMapKey (a, b) where<br />
data GMap (a, b) v = GMapPair (GMap a (GMap b v))<br />
empty = GMapPair empty<br />
lookup (a, b) (GMapPair gm) = lookup a gm >>= lookup b <br />
insert (a, b) v (GMapPair gm) = GMapPair $ case lookup a gm of<br />
Nothing -> insert a (insert b v empty) gm<br />
Just gm2 -> insert a (insert b v gm2 ) gm<br />
<br />
instance (GMapKey a, GMapKey b) => GMapKey (Either a b) where<br />
data GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)<br />
empty = GMapEither empty empty<br />
lookup (Left a) (GMapEither gm1 _gm2) = lookup a gm1<br />
lookup (Right b) (GMapEither _gm1 gm2 ) = lookup b gm2<br />
insert (Left a) v (GMapEither gm1 gm2) = GMapEither (insert a v gm1) gm2<br />
insert (Right b) v (GMapEither gm1 gm2) = GMapEither gm1 (insert b v gm2)<br />
</haskell><br />
If you find this code algorithmically surprising, I'd suggest to have a look at [http://www.cs.ox.ac.uk/ralf.hinze/publications/index.html#J4 Ralf Hinze's paper]. The only novelty concerning associated types, in these two instances, is that the instances have a context <hask>(GMapKey a, GMapKey b)</hask>. Consequently, the right hand sides of the associated type declarations can use <hask>GMap</hask> recursively at the key types <hask>a</hask> and <hask>b</hask> - not unlike the method definitions use the class methods recursively at the types for which the class is given in the instance context.<br />
<br />
=== Using a generic map ===<br />
<br />
Finally, some code building and querying a generic map:<br />
<haskell><br />
myGMap :: GMap (Int, Either Char ()) String<br />
myGMap = insert (5, Left 'c') "(5, Left 'c')" $<br />
insert (4, Right ()) "(4, Right ())" $<br />
insert (5, Right ()) "This is the one!" $<br />
insert (5, Right ()) "This is the two!" $<br />
insert (6, Right ()) "(6, Right ())" $<br />
insert (5, Left 'a') "(5, Left 'a')" $<br />
empty<br />
main = putStrLn $ maybe "Couldn't find key!" id $ lookup (5, Right ()) myGMap<br />
</haskell><br />
<br />
=== Download the code ===<br />
<br />
If you want to play with this example without copying it off the wiki, just download the source code[http://darcs.haskell.org/testsuite/tests/ghc-regress/indexed-types/should_run/GMapAssoc.hs] for <hask>GMap</hask> from GHC's test suite.<br />
<br />
== Detailed definition of data families ==<br />
<br />
Data families appear in two flavours: (1) they can be defined on the toplevel or (2) they can appear inside type classes (in which case they are known as associated types). The former is the more general variant, as it lacks the requirement for the type-indices to coincide with the class parameters. However, the latter can lead to more clearly structured code and compiler warnings if some type instances were - possibly accidentally - omitted. In the following, we always discuss the general toplevel form first and then cover the additional constraints placed on associated types.<br />
<br />
=== Family declarations ===<br />
<br />
Indexed data families are introduced by a signature, such as <br />
<haskell><br />
data family GMap k :: * -> *<br />
</haskell><br />
The special <hask>family</hask> distinguishes family from standard data declarations. The result kind annotation is optional and, as usual, defaults to <hask>*</hask> if omitted. An example is<br />
<haskell><br />
data family Array e<br />
</haskell><br />
Named arguments can also be given explicit kind signatures if needed. Just as with [http://www.haskell.org/ghc/docs/latest/html/users_guide/gadt.html GADT declarations] named arguments are entirely optional, so that we can declare <hask>Array</hask> alternatively with<br />
<haskell><br />
data family Array :: * -> *<br />
</haskell><br />
<br />
==== Associated family declarations ====<br />
<br />
When a data family is declared as part of a type class, we drop the <hask>family</hask> keyword. The <hask>GMap</hask> declaration takes the following form<br />
<haskell><br />
class GMapKey k where<br />
data GMap k :: * -> *<br />
...<br />
</haskell><br />
In contrast to toplevel declarations, named arguments must be used for all type parameters that are to be used as type-indices. Moreover, the argument names must be class parameters. Each class parameter may only be used at most once per associated type, but some may be omitted and they may be in an order other than in the class head. In other words: '''the named type parameters of the data declaration must be a permutation of a subset of the class variables'''. <br />
<br />
Example is admissible:<br />
<haskell><br />
class C a b c where { data T c a :: * } -- OK<br />
class C a b c where { data T a a :: * } -- Bad: repeated variable<br />
class D a where { data T a x :: * } -- Bad: x is not a class variable<br />
class D a where { data T a :: * -> * } -- OK<br />
</haskell><br />
<br />
=== Instance declarations ===<br />
<br />
Instance declarations of data and newtype families are very similar to standard data and newtype declarations. The only two differences are that the keyword <hask>data</hask> or <hask>newtype</hask> is followed by <hask>instance</hask> and that some or all of the type arguments can be non-variable types, but may not contain forall types or type synonym families. However, data families are generally allowed in type parameters, and type synonyms are allowed as long as they are fully applied and expand to a type that is itself admissible - exactly as this is required for occurrences of type synonyms in class instance parameters. For example, the <hask>Either</hask> instance for <hask>GMap</hask> is<br />
<haskell><br />
data instance GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)<br />
</haskell><br />
In this example, the declaration has only one variant. In general, it can be any number.<br />
<br />
Data and newtype instance declarations are only legit when an appropriate family declaration is in scope - just like class instances require the class declaration to be visible. Moreover, each instance declaration has to conform to the kind determined by its family declaration. This implies that the number of parameters of an instance declaration matches the arity determined by the kind of the family. Although all data families are declared with the <hask>data</hask> keyword, instances can be either <hask>data</hask> or <hask>newtype</hask>s, or a mix of both.<br />
<br />
Even if type families are defined as toplevel declarations, functions that perform different computations for different family instances still need to be defined as methods of type classes. In particular, the following is not possible:<br />
<haskell><br />
data family T a<br />
data instance T Int = A<br />
data instance T Char = B<br />
nonsense :: T a -> Int<br />
nonsense A = 1 -- WRONG: These two equations together...<br />
nonsense B = 2 -- ...will produce a type error.<br />
</haskell><br />
Given the functionality provided by GADTs (Generalised Algebraic Data Types), it might seem as if a definition, such as the above, should be feasible. However, type families - in contrast to GADTs - are ''open''; i.e., new instances can always be added, possibly in other modules. Supporting pattern matching across different data instances would require a form of extensible case construct.<br />
<br />
==== Associated type instances ====<br />
<br />
When an associated family instance is declared within a type class instance, we drop the <hask>instance</hask> keyword in the family instance. So, the <hask>Either</hask> instance for <hask>GMap</hask> becomes:<br />
<haskell><br />
instance (GMapKey a, GMapKey b) => GMapKey (Either a b) where<br />
data GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)<br />
...<br />
</haskell><br />
The most important point about associated family instances is that the type indices corresponding to class parameters must be identical to the type given in the instance head; here this is the first argument of <hask>GMap</hask>, namely <hask>Either a b</hask>, which coincides with the only class parameter. Any parameters to the family constructor that do not correspond to class parameters, need to be variables in every instance; here this is the variable <hask>v</hask>.<br />
<br />
Instances for an associated family can only appear as part of instance declarations of the class in which the family was declared - just as with the equations of the methods of a class. Also in correspondence to how methods are handled, declarations of associated types can be omitted in class instances. If an associated family instance is omitted, the corresponding instance type is not inhabited; i.e., only diverging expressions, such as <hask>undefined</hask>, can assume the type.<br />
<br />
==== Scoping of class parameters ====<br />
<br />
In the case of multi-parameter type classes, the visibility of class parameters in the right-hand side of associated family instances depends ''solely'' on the parameters of the data family. As an example, consider the simple class declaration<br />
<haskell><br />
class C a b where<br />
data T a<br />
</haskell><br />
Only one of the two class parameters is a parameter to the data family. Hence, the following instance declaration is invalid:<br />
<haskell><br />
instance C [c] d where<br />
data T [c] = MkT (c, d) -- WRONG!! 'd' is not in scope<br />
</haskell><br />
Here, the right-hand side of the data instance mentions the type variable <hask>d</hask> that does not occur in its left-hand side. We cannot admit such data instances as they would compromise type safety.<br />
<br />
==== Type class instances of family instances ====<br />
<br />
Type class instances of instances of data families can be defined as usual, and in particular data instance declarations can have <hask>deriving</hask> clauses. For example, we can write<br />
<haskell><br />
data GMap () v = GMapUnit (Maybe v)<br />
deriving Show<br />
</haskell><br />
which implicitly defines an instance of the form<br />
<haskell><br />
instance Show v => Show (GMap () v) where ...<br />
</haskell><br />
<br />
Note that class instances are always for particular ''instances'' of a data family and never for an entire family as a whole. This is for essentially the same reasons that we cannot define a toplevel function that performs pattern matching on the data constructors of ''different'' instances of a single type family. It would require a form of extensible case construct.<br />
<br />
==== Overlap ====<br />
<br />
The instance declarations of a data family used in a single program may not overlap at all, independent of whether they are associated or not. In contrast to type class instances, this is not only a matter of consistency, but one of type safety.<br />
<br />
=== Import and export ===<br />
<br />
The association of data constructors with type families is more dynamic than that is the case with standard data and newtype declarations. In the standard case, the notation <hask>T(..)</hask> in an import or export list denotes the type constructor and all the data constructors introduced in its declaration. However, a family declaration never introduces any data constructors; instead, data constructors are introduced by family instances. As a result, which data constructors are associated with a type family depends on the currently visible instance declarations for that family. Consequently, an import or export item of the form <hask>T(..)</hask> denotes the family constructor and all currently visible data constructors - in the case of an export item, these may be either imported or defined in the current module. The treatment of import and export items that explicitly list data constructors, such as <hask>GMap(GMapEither)</hask>, is analogous.<br />
<br />
==== Associated families ====<br />
<br />
As expected, an import or export item of the form <hask>C(..)</hask> denotes all of the class' methods and associated types. However, when associated types are explicitly listed as subitems of a class, we need some new syntax, as uppercase identifiers as subitems are usually data constructors, not type constructors. To clarify that we denote types here, each associated type name needs to be prefixed by the keyword <hask>type</hask>. So for example, when explicitly listing the components of the <hask>GMapKey</hask> class, we write <hask>GMapKey(type GMap, empty, lookup, insert)</hask>.<br />
<br />
==== Examples ====<br />
<br />
Assuming our running <hask>GMapKey</hask> class example, let us look at some export lists and their meaning:<br />
<br />
* <hask>module GMap (GMapKey) where...</hask>: Exports just the class name.<br />
* <hask>module GMap (GMapKey(..)) where...</hask>: Exports the class, the associated type <hask>GMap</hask> and the member functions <hask>empty</hask>, <hask>lookup</hask>, and <hask>insert</hask>. None of the data constructors is exported.<br />
* <hask>module GMap (GMapKey(..), GMap(..)) where...</hask>: As before, but also exports all the data constructors <hask>GMapInt</hask>, <hask>GMapChar</hask>, <hask>GMapUnit</hask>, <hask>GMapPair</hask>, and <hask>GMapEither</hask>.<br />
* <hask>module GMap (GMapKey(empty, lookup, insert), GMap(..)) where...</hask>: As before.<br />
* <hask>module GMap (GMapKey, empty, lookup, insert, GMap(..)) where...</hask>: As before.<br />
<br />
Finally, you can write <hask>GMapKey(type GMap)</hask> to denote both the class <hask>GMapKey</hask> as well as its associated type <hask>GMap</hask>. However, you cannot write <hask>GMapKey(type GMap(..))</hask> &mdash; i.e., sub-component specifications cannot be nested. To specify <hask>GMap</hask>'s data constructors, you have to list it separately.<br />
<br />
==== Instances ====<br />
<br />
Family instances are implicitly exported, just like class instances. However, this applies only to the heads of instances, not to the data constructors an instance defines.<br />
<br />
== An associated type synonym example ==<br />
<br />
Type synonym families are an alternative to functional dependencies, which makes functional dependency examples well suited to introduce type synonym families. In fact, type families are a more functional way to express the same as functional dependencies (despite the name!), as they replace the relational notation of functional dependencies by an expression-oriented notation; i.e., functions on types are really represented by functions and not relations.<br />
<br />
=== The <hask>class</hask> declaration ===<br />
<br />
Here's an example from Mark Jones' seminal paper on functional dependencies:<br />
<haskell><br />
class Collects e ce | ce -> e where<br />
empty :: ce<br />
insert :: e -> ce -> ce<br />
member :: e -> ce -> Bool<br />
toList :: ce -> [e]<br />
</haskell><br />
<br />
With associated type synonyms we can write this as<br />
<haskell><br />
class Collects ce where<br />
type Elem ce<br />
empty :: ce<br />
insert :: Elem ce -> ce -> ce<br />
member :: Elem ce -> ce -> Bool<br />
toList :: ce -> [Elem ce]<br />
</haskell><br />
Instead of the multi-parameter type class, we use a single parameter class, and the parameter <hask>e</hask><br />
turned into an associated type synonym <hask>Elem ce</hask>.<br />
<br />
=== An <hask>instance</hask>===<br />
<br />
Instances change correspondingly. An instance of the two-parameter class<br />
<haskell><br />
instance Eq e => Collects e [e] where<br />
empty = []<br />
insert e l = (e:l)<br />
member e [] = False<br />
member e (x:xs) <br />
| e == x = True<br />
| otherwise = member e xs<br />
toList l = l<br />
</haskell><br />
becomes an instance of a single-parameter class, where the dependent type parameter turns into an associated type instance declaration:<br />
<haskell><br />
instance Eq e => Collects [e] where<br />
type Elem [e] = e<br />
empty = []<br />
insert e l = (e:l)<br />
member e [] = False<br />
member e (x:xs) <br />
| e == x = True<br />
| otherwise = member e xs<br />
toList l = l<br />
</haskell><br />
<br />
=== Using generic collections ===<br />
<br />
With Functional Dependencies the code would be:<br />
<haskell><br />
sumCollects :: (Collects e c1, Collects e c2) => c1 -> c2 -> c2<br />
sumCollects c1 c2 = foldr insert c2 (toList c1)<br />
</haskell><br />
<br />
In contrast, with associated type synonyms, we get:<br />
<haskell><br />
sumCollects :: (Collects c1, Collects c2, Elem c1 ~ Elem c2) => c1 -> c2 -> c2<br />
sumCollects c1 c2 = foldr insert c2 (toList c1)<br />
</haskell><br />
<br />
== Detailed definition of type synonym families ==<br />
<br />
Type families appear in two flavours: (1) they can be defined on the toplevel or (2) they can appear inside type classes (in which case they are known as associated type synonyms). The former is the more general variant, as it lacks the requirement for the type-indices to coincide with the class parameters. However, the latter can lead to more clearly structured code and compiler warnings if some type instances were - possibly accidentally - omitted. In the following, we always discuss the general toplevel form first and then cover the additional constraints placed on associated types.<br />
<br />
=== Family declarations ===<br />
<br />
Indexed type families are introduced by a signature, such as <br />
<haskell><br />
type family Elem c :: *<br />
</haskell><br />
The special <hask>family</hask> distinguishes family from standard type declarations. The result kind annotation is optional and, as usual, defaults to <hask>*</hask> if omitted. An example is<br />
<haskell><br />
type family Elem c<br />
</haskell><br />
Parameters can also be given explicit kind signatures if needed. We call the number of parameters in a type family declaration, the family's arity, and all applications of a type family must be fully saturated w.r.t. to that arity. This requirement is unlike ordinary type synonyms and it implies that the kind of a type family is not sufficient to determine a family's arity, and hence in general, also insufficient to determine whether a type family application is well formed. As an example, consider the following declaration:<br />
<haskell><br />
type family F a b :: * -> * -- F's arity is 2, <br />
-- although its overall kind is * -> * -> * -> *<br />
</haskell><br />
Given this declaration the following are examples of well-formed and malformed types:<br />
<haskell><br />
F Char [Int] -- OK! Kind: * -> *<br />
F Char [Int] Bool -- OK! Kind: *<br />
F IO Bool -- WRONG: kind mismatch in the first argument<br />
F Bool -- WRONG: unsaturated application<br />
</haskell><br />
<br />
A top-level type family can be declared as open or closed. (Associated type<br />
families are always open.) A closed type family has all of its equations<br />
defined in one place and cannot be extended, whereas an open family can have<br />
instances spread across modules. The advantage of a closed family is that<br />
its equations are tried in order, similar to a term-level function definition:<br />
<haskell><br />
type family G a where<br />
G Int = Bool<br />
G a = Char<br />
</haskell><br />
With this definition, the type <hask>G Int</hask> becomes <hask>Bool</hask><br />
and, say, <hask>G Double</hask> becomes <hask>Char</hask>. See also [http://ghc.haskell.org/trac/ghc/wiki/NewAxioms here] for more information about closed type families.<br />
<br />
==== Associated family declarations ====<br />
<br />
When a type family is declared as part of a type class, we drop the <hask>family</hask> special. The <hask>Elem</hask> declaration takes the following form<br />
<haskell><br />
class Collects ce where<br />
type Elem ce :: *<br />
...<br />
</haskell><br />
Exactly as in the case of an associated data declaration, '''the named type parameters must be a permutation of a subset of the class parameters'''. Examples<br />
<haskell><br />
class C a b c where { type T c a :: * } -- OK<br />
class D a where { type T a x :: * } -- No: x is not a class parameter<br />
class D a where { type T a :: * -> * } -- OK<br />
</haskell><br />
<br />
=== Type instance declarations ===<br />
<br />
Instance declarations of open type families are very similar to standard type synonym declarations. The only two differences are that the keyword <hask>type</hask> is followed by <hask>instance</hask> and that some or all of the type arguments can be non-variable types, but may not contain forall types or type synonym families. However, data families are generally allowed, and type synonyms are allowed as long as they are fully applied and expand to a type that is admissible - these are the exact same requirements as for data instances. For example, the <hask>[e]</hask> instance for <hask>Elem</hask> is<br />
<haskell><br />
type instance Elem [e] = e<br />
</haskell><br />
<br />
A type family instance declaration must satisfy the following rules:<br />
* An appropriate family declaration is in scope - just like class instances require the class declaration to be visible. <br />
* The instance declaration conforms to the kind determined by its family declaration<br />
* The number of type parameters in an instance declaration matches the number of type parameters in the family declaration.<br />
* The right-hand side of a type instance must be a monotype (i.e., it may not include foralls) and after the expansion of all saturated vanilla type synonyms, no synonyms, except family synonyms may remain.<br />
<br />
Here are some examples of admissible and illegal type instances and closed families:<br />
<haskell><br />
type family F a :: *<br />
type instance F [Int] = Int -- OK!<br />
type instance F String = Char -- OK!<br />
type instance F (F a) = a -- WRONG: type parameter mentions a type family<br />
type instance F (forall a. (a, b)) = b -- WRONG: a forall type appears in a type parameter<br />
type instance F Float = forall a.a -- WRONG: right-hand side may not be a forall type<br />
<br />
type family F2 a where -- OK!<br />
F (Maybe Int) = Int<br />
F (Maybe Bool) = Bool<br />
F (Maybe a) = String<br />
<br />
type family G a b :: * -> *<br />
type instance G Int = (,) -- WRONG: must be two type parameters<br />
type instance G Int Char Float = Double -- WRONG: must be two type parameters<br />
</haskell><br />
<br />
==== Closed family simplification ====<br />
<br />
Included in ghc starting 7.8.1.<br />
<br />
When dealing with closed families, simplifying the type is harder than just finding a left-hand side that matches and replacing that with a right-hand side. GHC will select an equation to use in a given type family application (the "target") if and only if the following 2 conditions hold:<br />
<br />
# There is a substitution from the variables in the equation's LHS that makes the left-hand side of the branch coincide with the target.<br />
# For each previous equation in the family: either the LHS of that equation is ''apart'' from the type family application, '''or''' the equation is ''compatible'' with the chosen equation.<br />
<br />
Now, we define ''apart'' and ''compatible'':<br />
# Two types are ''apart'' when one cannot simplify to the other, even after arbitrary type-family simplifications<br />
# Two equations are ''compatible'' if, either, their LHSs are apart or their LHSs unify and their RHSs are the same under the substitution induced by the unification.<br />
<br />
Some examples are in order:<br />
<haskell><br />
type family F a where<br />
F Int = Bool<br />
F Bool = Char<br />
F a = Bool<br />
<br />
type family And (a :: Bool) (b :: Bool) :: Bool where<br />
And False c = False<br />
And True d = d<br />
And e False = False<br />
And f True = f<br />
And g g = g<br />
</haskell><br />
<br />
In <hask>F</hask>, all pairs of equations are compatible except the second and third. The first two are compatible because their LHSs are apart. The first and third are compatible because the unifying substitution leads the RHSs to be the same. But, the second and third are not compatible because neither of these conditions holds. As a result, GHC will not use the third equation to simplify a target unless that target is apart from <hask>Bool</hask>.<br />
<br />
In <hask>And</hask>, ''every'' pair of equations is compatible, meaning GHC never has to make the extra apartness check during simplification.<br />
<br />
Why do all of this? It's a matter of type safety. Consider this example:<br />
<br />
<haskell><br />
type family J a b where<br />
J a a = Int<br />
J a b = Bool<br />
</haskell><br />
<br />
Say GHC selected the second branch just because the first doesn't apply at the moment, because two type variables are distinct. The problem is that those variables might later be instantiated at the same value, and then the first branch would have applied. You can convince this sort of inconsistency to produce <hask>unsafeCoerce</hask>.<br />
<br />
It gets worse. GHC has no internal notion of inequality, so it can't use previous, failed term-level GADT pattern matches to refine its type assumptions. For example:<br />
<br />
<haskell><br />
data G :: * -> * where<br />
GInt :: G Int<br />
GBool :: G Bool<br />
<br />
type family Foo (a :: *) :: * where<br />
Foo Int = Char<br />
Foo a = Double<br />
<br />
bar :: G a -> Foo a<br />
bar GInt = 'x'<br />
bar _ = 3.14<br />
</haskell><br />
<br />
The last line will fail to typecheck, because GHC doesn't know that the type variable <hask>a</hask> can't be <hask>Int</hask> here, even though it's obvious. The only general way to fix this is to have inequality evidence introduced into GHC, and that's a big deal and we don't know if we have the motivation for such a change yet.<br />
<br />
==== Associated type instances ====<br />
<br />
When an associated family instance is declared within a type class instance, we drop the <hask>instance</hask> keyword in the family instance. So, the <hask>[e]</hask> instance for <hask>Elem</hask> becomes:<br />
<haskell><br />
instance (Eq (Elem [e])) => Collects ([e]) where<br />
type Elem [e] = e<br />
...<br />
</haskell><br />
The most important point about associated family instances is that the type indexes corresponding to class parameters must be identical to the type given in the instance head; here this is <hask>[e]</hask>, which coincides with the only class parameter.<br />
<br />
Instances for an associated family can only appear as part of instance declarations of the class in which the family was declared - just as with the equations of the methods of a class. Also in correspondence to how methods are handled, declarations of associated types can be omitted in class instances. If an associated family instance is omitted, the corresponding instance type is not inhabited; i.e., only diverging expressions, such as <hask>undefined</hask>, can assume the type.<br />
<br />
==== Overlap ====<br />
<br />
The instance declarations of an open type family used in a single program must be compatible, in the form defined above. This condition is independent of whether the type family is associated or not, and it is not only a matter of consistency, but one of type safety. <br />
<br />
Here are two examples to illustrate the condition under which overlap is permitted.<br />
<haskell><br />
type instance F (a, Int) = [a]<br />
type instance F (Int, b) = [b] -- overlap permitted<br />
<br />
type instance G (a, Int) = [a]<br />
type instance G (Char, a) = [a] -- ILLEGAL overlap, as [Char] /= [Int]<br />
</haskell><br />
<br />
==== Decidability ====<br />
<br />
In order to guarantee that type inference in the presence of type families is decidable, we need to place a number of additional restrictions on the formation of type instance declarations (c.f., Definition 5 (Relaxed Conditions) of [http://www.cse.unsw.edu.au/~chak/papers/SPCS08.html Type Checking with Open Type Functions]). Instance declarations have the general form<br />
<haskell><br />
type instance F t1 .. tn = t<br />
</haskell><br />
where we require that for every type family application <hask>(G s1 .. sm)</hask> in <hask>t</hask>, <br />
# <hask>s1 .. sm</hask> do not contain any type family constructors,<br />
# the total number of symbols (data type constructors and type variables) in <hask>s1 .. sm</hask> is strictly smaller than in <hask>t1 .. tn</hask>, and<br />
# for every type variable <hask>a</hask>, <hask>a</hask> occurs in <hask>s1 .. sm</hask> at most as often as in <hask>t1 .. tn</hask>.<br />
These restrictions are easily verified and ensure termination of type inference. However, they are not sufficient to guarantee completeness of type inference in the presence of, so called, ''loopy equalities'', such as <hask>a ~ [F a]</hask>, where a recursive occurrence of a type variable is underneath a family application and data constructor application - see the above mentioned paper for details. <br />
<br />
If the option <tt>-XUndecidableInstances</tt> is passed to the compiler, the above restrictions are not enforced and it is on the programmer to ensure termination of the normalisation of type families during type inference.<br />
<br />
=== Equality constraints ===<br />
<br />
Type context can include equality constraints of the form <hask>t1 ~ t2</hask>, which denote that the types <hask>t1</hask> and <hask>t2</hask> need to be the same. In the presence of type families, whether two types are equal cannot generally be decided locally. Hence, the contexts of function signatures may include equality constraints, as in the following example:<br />
<haskell><br />
sumCollects :: (Collects c1, Collects c2, Elem c1 ~ Elem c2) => c1 -> c2 -> c2<br />
</haskell><br />
where we require that the element type of <hask>c1</hask> and <hask>c2</hask> are the same. In general, the types <hask>t1</hask> and <hask>t2</hask> of an equality constraint may be arbitrary monotypes; i.e., they may not contain any quantifiers, independent of whether higher-rank types are otherwise enabled.<br />
<br />
Equality constraints can also appear in class and instance contexts. The former enable a simple translation of programs using functional dependencies into programs using family synonyms instead. The general idea is to rewrite a class declaration of the form<br />
<haskell><br />
class C a b | a -> b<br />
</haskell><br />
to<br />
<haskell><br />
class (F a ~ b) => C a b where<br />
type F a<br />
</haskell><br />
That is, we represent every functional dependency (FD) <hask>a1 .. an -> b</hask> by an FD type family <hask>F a1 .. an</hask> and a superclass context equality <hask>F a1 .. an ~ b</hask>, essentially giving a name to the functional dependency. In class instances, we define the type instances of FD families in accordance with the class head. Method signatures are not affected by that process.<br />
<br />
== Frequently asked questions ==<br />
<br />
=== Comparing type families and functional dependencies ===<br />
<br />
Functional dependencies cover some of the same territory as type families. How do the two compare?<br />
There are some articles about this question:<br />
<br />
* Experiences in converting functional dependencies to type families: "[[Functional dependencies vs. type families]]"<br />
* [http://hackage.haskell.org/trac/ghc/wiki/TFvsFD GHC trac] on a comparison of functional dependencies and type families<br />
<br />
=== Injectivity, type inference, and ambiguity ===<br />
<br />
A common problem is this<br />
<haskell><br />
type family F a<br />
<br />
f :: F a -> F a<br />
f = undefined<br />
<br />
g :: F Int -> F Int<br />
g x = f x<br />
</haskell><br />
The compiler complains about the definition of <tt>g</tt> saying<br />
<code><br />
Couldn't match expected type `F Int' against inferred type `F a1'<br />
</code><br />
In type-checking <tt>g</tt>'s right hand side GHC discovers (by instantiating <tt>f</tt>'s type with a fresh type variable) that it has type <tt>F a1 -> F a1</tt> for some as-yet-unknown type <tt>a1</tt>. Now it tries to make the inferred type match <tt>g</tt>'s type signature. Well, you say, just make <tt>a1</tt> equal to <tt>Int</tt> and you are done. True, but what if there were these instances<br />
<haskell><br />
type instance F Int = Bool<br />
type instance F Char = Bool<br />
</haskell><br />
Then making <tt>a1</tt> equal to <tt>Char</tt> would ''also'' make the two types equal. Because there is (potentially) more than one choice, the program is rejected.<br />
<br />
However (and confusingly) if you omit the type signature on <tt>g</tt> altogether, thus<br />
<haskell><br />
f :: F a -> F a<br />
f = undefined<br />
<br />
g x = f x<br />
</haskell><br />
GHC will happily infer the type <tt>g :: F a -> F a</tt>. But you can't ''write'' that type signature or, indeed, the more specific one above. (Arguably this behaviour, where GHC ''infers'' a type it can't ''check'', is very confusing. I suppose we could make GHC reject both programs, with and without type signatures.)<br />
<br />
'''What is the problem?''' The nub of the issue is this: knowing that <tt>F t1</tt>=<tt>F t2</tt> does ''not'' imply that <tt>t1</tt> = <tt>t2</tt>.<br />
The difficulty is that the type function <tt>F</tt> need not be ''injective''; it can map two distinct types to the same type. For an injective type constructor like <tt>Maybe</tt>, if we know that <tt>Maybe t1</tt> = <tt>Maybe t2</tt>, then we know that <tt>t1</tt> = <tt>t2</tt>. But not so for non-injective type functions.<br />
<br />
The problem starts with <tt>f</tt>. Its type is ''ambiguous''; even if I know the argument and result types for <tt>f</tt>, I cannot use that to find the type at which <tt>a</tt> should be instantiated. (So arguably, <tt>f</tt> should be rejected as having an ambiguous type, and probably will be in future.) The situation is well known in type classes: <br />
<haskell><br />
bad :: (Read a, Show a) => String -> String<br />
bad x = show (read x)<br />
</haskell><br />
At a call of <tt>bad</tt> one cannot tell at what type <tt>a</tt> should be instantiated.<br />
<br />
The only solution is to avoid ambiguous types. In the type signature of a function, <br />
* Ensure that every type variable occurs in the part after the "<tt>=></tt>"<br />
* Ensure that every type variable appears at least once outside a type function call.<br />
Alternatively, you can use data families, which create new types and are therefore injective. The following code works:<br />
<br />
<haskell>data family F a<br />
<br />
f :: F a -> F a<br />
f = undefined<br />
<br />
g :: F Int -> F Int<br />
g x = f x</haskell><br />
<br />
== References ==<br />
<br />
* [http://www.cse.unsw.edu.au/~chak/papers/CKPM05.html Associated Types with Class.] Manuel M. T. Chakravarty, Gabriele Keller, Simon Peyton Jones, and Simon Marlow. In ''Proceedings of The 32nd Annual ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages (POPL'05)'', pages 1-13, ACM Press, 2005.<br />
* [http://www.cse.unsw.edu.au/~chak/papers/CKP05.html Associated Type Synonyms.] Manuel M. T. Chakravarty, Gabriele Keller, and Simon Peyton Jones. In ''Proceedings of The Tenth ACM SIGPLAN International Conference on Functional Programming'', ACM Press, pages 241-253, 2005.<br />
* [http://www.cse.unsw.edu.au/~chak/papers/SCPD07.html System F with Type Equality Coercions.] Martin Sulzmann, Manuel M. T. Chakravarty, Simon Peyton Jones, and Kevin Donnelly. In ''Proceedings of The Third ACM SIGPLAN Workshop on Types in Language Design and Implementation'', ACM Press, 2007.<br />
* [http://www.cse.unsw.edu.au/~chak/papers/SPCS08.html Type Checking With Open Type Functions.] Tom Schrijvers, Simon Peyton-Jones, Manuel M. T. Chakravarty, Martin Sulzmann. In ''Proceedings of The 13th ACM SIGPLAN International Conference on Functional Programming'', ACM Press, pages 51-62, 2008.<br />
* [[Simonpj/Talk:FunWithTypeFuns | Fun with Type Functions]] Oleg Kiselyov, Simon Peyton Jones, Chung-chieh Shan (the source for this paper can be found at http://patch-tag.com/r/schoenfinkel/typefunctions/wiki ) <br />
<br />
[[Category:Type-level programming]]<br />
[[Category:Language extensions]]<br />
[[Category:GHC|Indexed types]]</div>Shahnhttps://wiki.haskell.org/index.php?title=Web/Frameworks&diff=59464Web/Frameworks2015-02-28T10:53:06Z<p>Shahn: Add servant</p>
<hr />
<div>[[Category:Web|*]]<br />
{{Web infobox}}<br />
<br />
Content from [[Web]] should be merged here.<br />
<br />
Below is a list of known to be active Haskell web frameworks. Rather than one framework to rule them all, Haskell provides several options. You can view the [[Web/Deploy]] page to get an idea of how you might deploy an application written in some of these frameworks.<br />
<br />
See also: there are also many [[Web/Frameworks/Inactive|inactive web frameworks]] to draw inspiration from<br />
<br />
== Happstack ==<br />
<br />
Happstack is a Haskell web framework. Happstack is designed so that developers can prototype quickly, deploy painlessly, scale massively, operate reliably, and change easily. It supports GNU/Linux, OS X, FreeBSD, and Windows environments.<br />
<br />
{| class="wikitable"<br />
! License<br />
| BSD3<br />
|-<br />
! Author:<br />
| Happstack team, HAppS LLC<br />
|-<br />
! Maintainer:<br />
| Happstack team <happs@googlegroups.com><br />
|-<br />
! Home page:<br />
| http://happstack.com/<br />
|-<br />
! Documentation:<br />
| http://www.happstack.com/c/view-page-slug/3/documentation/<br />
|-<br />
! Package & repositories<br />
| [http://hackage.haskell.org/package/happstack-server Hackage] - [http://patch-tag.com/r/mae/happstack Darcs]<br />
|}<br />
<br />
[http://happstack.com/ Happstack] is a complete web framework. The main component is [http://hackage.haskell.org/package/happstack-server happstack-server]: an integrated HTTP server, routing combinators, fileserving, etc. In addition, a number of packages that used to be coupled to Happstack have now been decoupled from it, but remain promoted and documented for use with Happstack:<br />
<br />
* [http://hackage.haskell.org/package/safecopy safecopy]: datatype serialization and migration support<br />
* [http://hackage.haskell.org/package/acid-state acid-state]: a powerful NoSQL ACID storage system with native support for Haskell types<br />
<br />
It also includes integration with many 3rd party libraries including:<br />
<br />
*templating: [http://hackage.haskell.org/package/blaze-html Blaze HTML], [http://www.yesodweb.com/book/shakespearean-templates Hamlet], [[HSP]], [[HStringTemplate]], [[Heist]], and more<br />
*forms: [http://hackage.haskell.org/package/reform reform]<br />
*routing: [http://hackage.haskell.org/package/web-routes web-routes] type-safe urls and routing<br />
*databases: can be used with most [[Database interfaces]] with no special support required<br />
<br />
See the [http://happstack.com/ Happstack Home Page] for more information and to learn how to get support via IRC and mailing lists.<br />
<br />
== Snap ==<br />
<br />
Snap is a simple web development framework for unix systems, written in the Haskell programming language.<br />
<br />
Snap is well-documented and has a test suite with a high level of code coverage, but it is early-stage software with still-evolving interfaces. Snap is therefore likely to be most appropriate for early adopters and potential contributors.<br />
<br />
* A fast HTTP server library with an optional high-concurrency backend using the libev event loop library<br />
* A sensible and clean monad for web programming<br />
* An XML-based templating system for generating HTML<br />
<br />
{| class="wikitable"<br />
! License:<br />
| BSD3<br />
|-<br />
! Author:<br />
| James Sanders, Gregory Collins, Doug Beardsley<br />
|-<br />
! Maintainer:<br />
| snap@snapframework.com<br />
|-<br />
! Home page:<br />
| http://snapframework.com/<br />
|-<br />
! Documentation:<br />
| http://snapframework.com/docs<br />
|-<br />
! Package & repositories<br />
| [http://hackage.haskell.org/package/snap-server Hackage] - [http://git.snapframework.com/snap-server.git Git]<br />
|}<br />
<br />
== Yesod ==<br />
<br />
Yesod is designed for RESTful, type-safe, performant web apps. By leveraging quasi-quotation for the more boilerplate tasks, we get concise web apps with high levels of type safety. Its Hamlet templates are compile-time checked for correctness, and the controller (web-routes-quasi) uses type-safe URLs to make certain you are only generating valid URLs. It loosely follows Model/View/Controller principles.<br />
<br />
{| class="wikitable"<br />
! License:<br />
| BSD3<br />
|-<br />
! Author:<br />
| Michael Snoyman <michael@snoyman.com><br />
|-<br />
! Maintainer:<br />
| Michael Snoyman <michael@snoyman.com><br />
|-<br />
! Announcement:<br />
| http://www.haskell.org/pipermail/haskell-cafe/2010-March/074271.html<br />
|-<br />
! Home page:<br />
| http://www.yesodweb.com/<br />
|-<br />
! Documentation:<br />
| http://www.yesodweb.com/book<br />
|-<br />
! Screencast:<br />
| http://www.yesodweb.com/page/screencasts<br />
|-<br />
! Package & repositories<br />
| [http://hackage.haskell.org/package/yesod Hackage] - [https://github.com/yesodweb/yesod Github]<br />
|}<br />
<br />
[http://docs.yesodweb.com/ Yesod] is a full-featured web framework. It takes a modular approach to development, so many parts of the framework such as [http://www.yesodweb.com/book/shakespearean-templates Hamlet] and [http://www.yesodweb.com/book/persistent Persistent] are available as standalone packages. However, put together, Yesod provides you with solutions for templating, routing, persistence, sessions, JSON, authentication/authorization, and more. Yesod's major guiding principle is type safety: if your application compiles, it works.<br />
<br />
Yesod is very well documented through a combination of haddocks and the [http://docs.yesodweb.com/book Yesod book].<br />
<br />
Yesod is built on [http://hackage.haskell.org/package/wai WAI], or the Web Application Interface. This is similar to WSGI in Python or Rack in Ruby. It provides a single interface that all applications can target and work on multiple backends. Backends exist for CGI, FastCGI, SCGI, development server (auto-recompile) and even a Webkit-powered desktop version.<br />
<br />
But the premier backend is [http://hackage.haskell.org/package/warp Warp]: a very simple web server which, at the time of writing, is the fastest Haskell has to offer. You can read more in its [http://docs.yesodweb.com/blog/announcing-warp release announcement] and see some [http://www.yesodweb.com/blog/2011/02/warp-speed-ahead followup benchmarks]. Warp is already powering Yesod; some other major players that are planning a move are Hoogle and Happstack.<br />
<br />
You can see a [https://github.com/yesodweb/yesod/wiki/Powered-by-Yesod list of Yesod-powered sites and packages], or check out the [https://github.com/snoyberg/haskellers source code for Haskellers]. Most discussions for Yesod take place on the [http://groups.google.com/group/yesodweb yesodweb list], so feel free to join in and ask any questions you have, the Yesod community is very beginner-friendly.<br />
<br />
== miku ==<br />
<br />
A simple library for fast web prototyping in Haskell, inspired by Ruby's Rack and Sinatra.<br />
<br />
{| class="wikitable"<br />
! License<br />
| BSD3<br />
|-<br />
! Author<br />
| Wang, Jinjing<br />
|-<br />
! Maintainer<br />
| Wang, Jinjing <nfjinjing@gmail.com><br />
|-<br />
! Package & repositories<br />
| [http://hackage.haskell.org/package/miku Hackage] - [http://github.com/nfjinjing/miku Github]<br />
|}<br />
<br />
== Lemmachine ==<br />
<br />
Lemmachine is a REST'ful web framework that makes it easy to get HTTP right by exposing users to overridable hooks with sane defaults. The main architecture is a copy of Erlang-based Webmachine, which is currently the best documentation reference (for hooks & general design).<br />
<br />
Lemmachine stands out from the dynamically typed Webmachine by being written in dependently typed Agda. The goal of the project is to show the advantages gained from compositional testing by taking advantage of proofs being inherently compositional. See proofs for examples of universally quantified proofs (tests over all possible input values) written against the default resource, which does not override any hooks.<br />
<br />
[http://github.com/larrytheliquid/Lemmachine#readme More information]<br />
<br />
{| class="wikitable"<br />
! Author<br />
| Larry Diehl<br />
|-<br />
! Packages & repositories<br />
| [http://github.com/larrytheliquid/Lemmachine Github]<br />
|}<br />
<br />
== mohws ==<br />
<br />
A web server with a module system and support for CGI. Based on Simon Marlow's original Haskell Web Server.<br />
<br />
{| class="wikitable"<br />
!License:<br />
|BSD3<br />
|-<br />
!Copyright:<br />
|Simon Marlow, Bjorn Bringert<br />
|-<br />
!Author:<br />
|Simon Marlow, Bjorn Bringert <bjorn@bringert.net><br />
|-<br />
!Maintainer:<br />
|Henning Thielemann <webserver@henning-thielemann.de><br />
|-<br />
!Packages & repositories<br />
|[http://hackage.haskell.org/cgi-bin/hackage-scripts/package/mohws Hackage] - [http://code.haskell.org/mohws/ Darcs]<br />
|}<br />
<br />
== Salvia ==<br />
<br />
Salvia is a feature rich modular web server and web application framework that can be used to write dynamic websites in Haskell. From the lower level protocol code up to the high level application code, everything is written as a Salvia handler. This approach makes the server extremely extensible. To see a demo of a Salvia website, please see the salvia-demo package.<br />
<br />
All the low level protocol code can be found in the salvia-protocol package, which exposes the datatypes, parsers and pretty-printers for the URI, HTTP, Cookie and MIME protocols.<br />
<br />
This Salvia package itself can be separated into three different parts: the interface, the handlers and the implementation. The interface module defines a number of type classes that the user can build the web application against. Reading the request object, writing to the response, or gaining direct access to the socket, all of these actions are reflected using one type class aspect in the interface. The handlers are self contained modules that implement a single aspect of the Salvia web server. The handlers expose their interface requirements in their type context. Salvia can have multiple implementations which can be switched by using different instances for the interface type classes. This package has only one implementation, a simple accepting socket loop server. The salvia-extras package has two additional implementations. Keeping a clear distinction between the abstract server aspects and the actual implementation makes it very easy to migrate existing web application to different back-ends.<br />
<br />
{| class="wikitable"<br />
! License:<br />
| BSD3<br />
|-<br />
! Author:<br />
| Sebastiaan Visser<br />
|-<br />
! Maintainer:<br />
| sfvisser@cs.uu.nl<br />
|-<br />
! Announcement:<br />
| http://www.haskell.org/pipermail/haskell-cafe/2010-March/074870.html<br />
|-<br />
! Package & repositories<br />
| [http://hackage.haskell.org/package/salvia Hackage] - [http://github.com/sebastiaanvisser/salvia Git]<br />
|}<br />
<br />
== Scotty ==<br />
<br />
A Haskell web framework inspired by Ruby's Sinatra, using WAI and Warp. Sinatra + Warp = Scotty.<br />
<br />
Scotty is the cheap and cheerful way to write RESTful, declarative web applications.<br />
<br />
* A page is as simple as defining the verb, url pattern, and Text content.<br />
* It is template-language agnostic. Anything that returns a Text value will do.<br />
* Conforms to WAI Application interface.<br />
* Uses very fast Warp webserver by default.<br />
<br />
{| class="wikitable"<br />
! License:<br />
| BSD3<br />
|-<br />
! Author:<br />
| Andrew Farmer<br />
|-<br />
! Maintainer:<br />
| Andrew Farmer<br />
|-<br />
! Home page:<br />
| https://github.com/scotty-web/scotty<br />
|-<br />
! Documentation:<br />
| http://hackage.haskell.org/package/scotty<br />
|-<br />
! Package & repositories<br />
| [http://hackage.haskell.org/package/scotty Hackage] - [https://github.com/scotty-web/scotty Git]<br />
|}<br />
<br />
== Servant ==<br />
<br />
Servant is a a light-weight framework primarily for REST APIs. It allows to specify API specifications as type aliases and then work with these type aliases to create servers, but also documentation, client code in Haskell and Javascript, etc.. It is based on wai.<br />
<br />
<br />
{| class="wikitable"<br />
! License:<br />
| BSD3<br />
|-<br />
! Author:<br />
| Alp Mestanogullari, Sönke Hahn, Julian K. Arni<br />
|-<br />
! Maintainer:<br />
| alpmestan@gmail.com<br />
|-<br />
! Home page:<br />
| http://haskell-servant.github.io/<br />
|-<br />
! Package & repositories<br />
| [http://hackage.haskell.org/package/servant Hackage] - [https://github.com/haskell-servant Git]<br />
|}<br />
<br />
== MFlow==<br />
<br />
A Haskell application server ++ Web Framework. MFlow is a shorthand for "Message Flow". It is a continuation-based framework without continuations. Instead of other continuation based frameworks like Ocsigen(Ocaml), Coccoon (javascript) or Seaside (Smalltalk), it is based on a backtracking monad that keep the synchornization of the execution state with the user navigation. Since the discontinuation of [http://www.informatik.uni-freiburg.de/~thiemann/WASH/ WASH], MFlow is the only continuation-style framework written in Haskell to date.<br />
<br />
Unlike real continuations, the state in MFlow applications is pretty small and serializable, so it is horizontally scalable. The navigation in a MFlow application is safe at compilation time, since even the internal HTML links are checked by the compiler. The code is very short and has little configuration. Routes in MFlow are defined and typechecked in pure haskell code, just like in the case of the menus in a console application. Each page has its own URL so it is RESTful to a certain extent. It is planned to have REST-style URLs in the future (done in the head of the github repo).<br />
<br />
It uses standard Haskell web libraries and/or techniques: WAI, Warp, Blaze HTML, HSP. Its core is server and rendering independent. A kind of extended [http://groups.inf.ed.ac.uk/links/formlets/ formlets] are used to create self contained components, called widgets. They have formatting, Ajax, and server code. They can be composed to create the user interface.<br />
<br />
A MFlow application resembles a console application. This is an example of a complete application with three pages. It ask for two numbers and return the sum. At any time, even if the user press the back button, the state is synchronized with the navigation. <br />
<br />
module Main where<br />
import MFlow.Wai.Blaze.Html.All<br />
<br />
main= do<br />
addMessageFlows [("sum", transient . runFlow $ sumIt )]<br />
wait $ run 8081 waiMessageFlow<br />
<br />
sumIt= do<br />
setHeader $ html . body<br />
n1 <- ask $ p << "give me the first number" <br />
++> getInt Nothing <br />
<** submitButton "send"<br />
<br />
n2 <- ask $ p << "give me the second number" <br />
++> getInt Nothing <br />
<** submitButton "send"<br />
<br />
ask $ p << ("the result is " ++ show (n1 + n2)) <br />
++> wlink () << p << "click here"<br />
<br />
<br />
<br />
{| class="wikitable"<br />
! License:<br />
| BSD3<br />
|-<br />
! Author:<br />
| Alberto Gómez Corona<br />
|-<br />
! Maintainer:<br />
| Alberto Gómez Corona<br />
|-<br />
! Home page:<br />
| http://haskell-web.blogspot.com<br />
|-<br />
! Documentation:<br />
| http://hackage.haskell.org/package/MFlow<br />
[https://docs.google.com/file/d/0B2-x2MmiuA32b0RndnZTdTVUb0E MFlow paper]<br />
|-<br />
! Package & repositories<br />
| [http://hackage.haskell.org/package/MFlow Hackage] - [https://github.com/agocorona/MFlow Git]<br />
|}<br />
<br />
== Spock ==<br />
<br />
Another Haskell web framework for rapid development: This toolbox provides everything you need to get a quick start into web hacking with haskell: routing, middleware, json, blaze, sessions, cookies, database helper, csrf-protection, global state<br />
<br />
* Simple API<br />
* Adds lots of useful features for rapid web development<br />
* Fast tree based routing<br />
* Plugins like [http://hackage.haskell.org/package/Spock-auth Spock-auth] and [http://hackage.haskell.org/package/Spock-worker Spock-worker]<br />
<br />
{| class="wikitable"<br />
! License:<br />
| BSD3<br />
|-<br />
! Author:<br />
| Alexander Thiemann<br />
|-<br />
! Maintainer:<br />
| Alexander Thiemann<br />
|-<br />
! Home page:<br />
| https://github.com/agrafix/Spock<br />
|-<br />
! Documentation:<br />
| http://hackage.haskell.org/package/Spock<br />
|-<br />
! Package & repositories<br />
| [http://hackage.haskell.org/package/Spock Hackage] - [https://github.com/agrafix/Spock Git]<br />
|}<br />
<br />
== Wheb ==<br />
<br />
Wheb's a WAI framework for building robust, high-concurrency web applications simply and effectively. Its primary goal is to extend the functionality of the base WAI library and to provide an easy entry point into Haskell web servers. The only prerequisite is "Learn you a Haskell" or another introductory Haskell course. It comes with lots of examples on the github page.<br />
<br />
* The core datatype will let you build anything from a read-only server to a fully interactive web application with basic Haskell.<br />
* Minimal boilerplate to start your application.<br />
* Session, Auth and Cache interfaces are built in. Just drop in a backend.<br />
* Choice between type-safe web-routes or simpler pattern-based named-routes.<br />
* Easy to use for REST APIs<br />
* WebSockets<br />
* Fully database and template agnostic<br />
* Easy handler debugging.<br />
* Middleware<br />
<br />
Wheb makes it easy to write plugins. Plugins can add routes, middleware, settings and even handle resource cleanup on server shutdown. Named routes allow plugins to dynamically generate their routes at runtime based on settings. <br />
<br />
* Sessions<br />
* Auth<br />
* Cache<br />
* [http://hackage.haskell.org/package/wheb-mongo Wheb-Mongo]<br />
* [http://hackage.haskell.org/package/wheb-redis Wheb-Redis]<br />
* [http://hackage.haskell.org/package/wheb-strapped Wheb-Strapped]<br />
<br />
{| class="wikitable"<br />
! License:<br />
| BSD3<br />
|-<br />
! Author:<br />
| Kyle Hanson<br />
|-<br />
! Maintainer:<br />
| Kyle Hanson<br />
|-<br />
! Home page:<br />
| https://github.com/hansonkd/Wheb-Framework<br />
|-<br />
! Documentation:<br />
| http://hackage.haskell.org/package/Wheb<br />
|}<br />
<br />
==See also==<br />
<br />
* [[Web/Framework survey]]</div>Shahnhttps://wiki.haskell.org/index.php?title=HkHac2012&diff=45504HkHac20122012-04-30T12:24:24Z<p>Shahn: /* Agenda */</p>
<hr />
<div>== About ==<br />
<br />
The purpose of Haskell hackathons traditionally is at least twofold: Code base improvement and community building. I am currently more interested in the second one, and looking forward to find out how far we can get with the first. --[[User:Mf|Mf]] 08:46, 30 April 2012 (UTC)<br />
<br />
If you want to participate, please add yourself in the People section below. If you have questions, please contact Matthias (mail: mf zerobuzz net, phone: +852 9582 5172).<br />
<br />
<br />
== Dates ==<br />
<br />
All dates still tentative. Please vote or suggest alternatives:<br />
<br />
* May 11-13<br />
* May 25-27<br />
<br />
I will be in HK until May 31, but of course I am not necessary for the event to be a success. - - [[User:Mf|Mf]] 11:39, 27 April 2012 (UTC) :)<br />
<br />
<br />
== Location ==<br />
<br />
We are still looking for a location. More on this soon.<br />
<br />
<br />
== People ==<br />
<br />
* Matthias (- - [[User:Mf|Mf]] 11:39, 27 April 2012 (UTC)). Would like to hack a SPKI C-binding and high-level PKI API.<br />
* Sönke Hahn (--[[User:Shahn|Shahn]] 12:13, 30 April 2012 (UTC)). I would like to attend, but I'm not sure I'll manage.<br />
<br />
== Agenda ==<br />
<br />
I have more than enough ideas for projects, but please everybody propose your own. I am more than happy to step back and do something you think is relevant. If you want to attend, please leave a note which projects you are most interested in.<br />
<br />
<br />
=== Implement SPKI ===<br />
<br />
Since SSL/TLS is notoriously convoluted and error prone (most recent evidence: http://lists.grok.org.uk/pipermail/full-disclosure/2012-April/086585.html), it may be time to make another effort to replace it. SPKI addresses many requirements that SSL/TLS does, but is much more concise and coherent.<br />
<br />
* Overview: http://world.std.com/~cme/html/spki.html<br />
* Standards: http://world.std.com/~cme/spki.txt, http://www.ietf.org/rfc/rfc2693.txt<br />
* Algorithms: Distributed Credential Chain in Trust Management, Proceedings of the 8th ACM Conference on Computer and Communications Security (CCS-8), pages 156–165, ACM Press, November 2001.<br />
<br />
The idea of this one is not so much to make something new, but to take something that is done in a language different from Haskell, and see how well it ports. This will not only give us a deeper understanding of both source and target language, but also make it more convenient to build applications in Haskell, and through interop testing will lead to better code in the original implementation as well.<br />
<br />
Variants: Take one of the implementations and build a C binding. Design an abstract PKI API that can be used to manipulate both x509/SSL and SPKI credentials. Implement a mapping between x509/SSL and SPKI credentials.<br />
<br />
<br />
=== Port ZooKeeper to Haskell ===<br />
<br />
* http://wiki.apache.org/hadoop/ZooKeeper<br />
<br />
Zookeeper is the distributed key/value store used for synchronisation in Hadoop, but intended for a much larger application space. A lot of skill and effort has gone into the design, implementation and testing, and it solves problems that all distributed applications have. I like this project.<br />
<br />
It would be totally hot if there was a Haskell implementation that could outperform the Apache Foundation's Java implementation. That is not a two-weekend project, but a ghc binding might be.<br />
<br />
<br />
=== Implement Kademlia in Haskell ===<br />
<br />
* Research paper explaining the algorithm: http://www.cs.rice.edu/Conferences/IPTPS02/109.pdf<br />
* Python implementation: http://entangled.sourceforge.net/<br />
<br />
Again: This could be done as a port, a binding, or a complete re-implementation.<br />
<br />
<br />
=== Play with adhocracy, liquid feedback, ... ===<br />
<br />
These are tools to help organize participatory and open political processes.<br />
<br />
* http://translate.google.ch/translate?sl=de&tl=en&js=n&prev=_t&hl=de&ie=UTF-8&layout=2&eotf=1&u=http%3A%2F%2Fde.wikipedia.org%2Fwiki%2FAdhocracy_%2528Software%2529<br />
* http://lists.liqd.net/cgi-bin/mailman/listinfo/adhocracy-dev<br />
* http://translate.google.ch/translate?hl=de&sl=de&tl=en&u=http%3A%2F%2Fde.wikipedia.org%2Fwiki%2FLiquidFeedback<br />
<br />
These are two projects I am curious about, but have not had to the time to look into. I know that one of them is running on adequate development resources, so if anybody is interested in this we could probably ask the project owners for challenges and chores.<br />
<br />
=== Cyclic Module Imports ===<br />
<br />
Cyclic module imports are possible by manually providing .hs-boot files. I think that cyclic module imports without the need for manual work would improve programming in the large. [http://hackage.haskell.org/trac/ghc/ticket/1409 This ticket] in the ghc trac suggests that someone has to come up with a sound design for this. I propose to discuss this during HkHac. (--[[User:Shahn|Shahn]] 12:24, 30 April 2012 (UTC))</div>Shahnhttps://wiki.haskell.org/index.php?title=HkHac2012&diff=45503HkHac20122012-04-30T12:13:09Z<p>Shahn: /* People */</p>
<hr />
<div>== About ==<br />
<br />
The purpose of Haskell hackathons traditionally is at least twofold: Code base improvement and community building. I am currently more interested in the second one, and looking forward to find out how far we can get with the first. --[[User:Mf|Mf]] 08:46, 30 April 2012 (UTC)<br />
<br />
If you want to participate, please add yourself in the People section below. If you have questions, please contact Matthias (mail: mf zerobuzz net, phone: +852 9582 5172).<br />
<br />
<br />
== Dates ==<br />
<br />
All dates still tentative. Please vote or suggest alternatives:<br />
<br />
* May 11-13<br />
* May 25-27<br />
<br />
I will be in HK until May 31, but of course I am not necessary for the event to be a success. - - [[User:Mf|Mf]] 11:39, 27 April 2012 (UTC) :)<br />
<br />
<br />
== Location ==<br />
<br />
We are still looking for a location. More on this soon.<br />
<br />
<br />
== People ==<br />
<br />
* Matthias (- - [[User:Mf|Mf]] 11:39, 27 April 2012 (UTC)). Would like to hack a SPKI C-binding and high-level PKI API.<br />
* Sönke Hahn (--[[User:Shahn|Shahn]] 12:13, 30 April 2012 (UTC)). I would like to attend, but I'm not sure I'll manage.<br />
<br />
== Agenda ==<br />
<br />
I have more than enough ideas for projects, but please everybody propose your own. I am more than happy to step back and do something you think is relevant. If you want to attend, please leave a note which projects you are most interested in.<br />
<br />
<br />
=== Implement SPKI ===<br />
<br />
Since SSL/TLS is notoriously convoluted and error prone (most recent evidence: http://lists.grok.org.uk/pipermail/full-disclosure/2012-April/086585.html), it may be time to make another effort to replace it. SPKI addresses many requirements that SSL/TLS does, but is much more concise and coherent.<br />
<br />
* Overview: http://world.std.com/~cme/html/spki.html<br />
* Standards: http://world.std.com/~cme/spki.txt, http://www.ietf.org/rfc/rfc2693.txt<br />
* Algorithms: Distributed Credential Chain in Trust Management, Proceedings of the 8th ACM Conference on Computer and Communications Security (CCS-8), pages 156–165, ACM Press, November 2001.<br />
<br />
The idea of this one is not so much to make something new, but to take something that is done in a language different from Haskell, and see how well it ports. This will not only give us a deeper understanding of both source and target language, but also make it more convenient to build applications in Haskell, and through interop testing will lead to better code in the original implementation as well.<br />
<br />
Variants: Take one of the implementations and build a C binding. Design an abstract PKI API that can be used to manipulate both x509/SSL and SPKI credentials. Implement a mapping between x509/SSL and SPKI credentials.<br />
<br />
<br />
=== Port ZooKeeper to Haskell ===<br />
<br />
* http://wiki.apache.org/hadoop/ZooKeeper<br />
<br />
Zookeeper is the distributed key/value store used for synchronisation in Hadoop, but intended for a much larger application space. A lot of skill and effort has gone into the design, implementation and testing, and it solves problems that all distributed applications have. I like this project.<br />
<br />
It would be totally hot if there was a Haskell implementation that could outperform the Apache Foundation's Java implementation. That is not a two-weekend project, but a ghc binding might be.<br />
<br />
<br />
=== Implement Kademlia in Haskell ===<br />
<br />
* Research paper explaining the algorithm: http://www.cs.rice.edu/Conferences/IPTPS02/109.pdf<br />
* Python implementation: http://entangled.sourceforge.net/<br />
<br />
Again: This could be done as a port, a binding, or a complete re-implementation.<br />
<br />
<br />
=== Play with adhocracy, liquid feedback, ... ===<br />
<br />
These are tools to help organize participatory and open political processes.<br />
<br />
* http://translate.google.ch/translate?sl=de&tl=en&js=n&prev=_t&hl=de&ie=UTF-8&layout=2&eotf=1&u=http%3A%2F%2Fde.wikipedia.org%2Fwiki%2FAdhocracy_%2528Software%2529<br />
* http://lists.liqd.net/cgi-bin/mailman/listinfo/adhocracy-dev<br />
* http://translate.google.ch/translate?hl=de&sl=de&tl=en&u=http%3A%2F%2Fde.wikipedia.org%2Fwiki%2FLiquidFeedback<br />
<br />
These are two projects I am curious about, but have not had to the time to look into. I know that one of them is running on adequate development resources, so if anybody is interested in this we could probably ask the project owners for challenges and chores.</div>Shahnhttps://wiki.haskell.org/index.php?title=HkHac2012&diff=45502HkHac20122012-04-30T12:07:57Z<p>Shahn: /* Play with adhocracy, liquid feedback, ... */</p>
<hr />
<div>== About ==<br />
<br />
The purpose of Haskell hackathons traditionally is at least twofold: Code base improvement and community building. I am currently more interested in the second one, and looking forward to find out how far we can get with the first. --[[User:Mf|Mf]] 08:46, 30 April 2012 (UTC)<br />
<br />
If you want to participate, please add yourself in the People section below. If you have questions, please contact Matthias (mail: mf zerobuzz net, phone: +852 9582 5172).<br />
<br />
<br />
== Dates ==<br />
<br />
All dates still tentative. Please vote or suggest alternatives:<br />
<br />
* May 11-13<br />
* May 25-27<br />
<br />
I will be in HK until May 31, but of course I am not necessary for the event to be a success. - - [[User:Mf|Mf]] 11:39, 27 April 2012 (UTC) :)<br />
<br />
<br />
== Location ==<br />
<br />
We are still looking for a location. More on this soon.<br />
<br />
<br />
== People ==<br />
<br />
* Matthias (- - [[User:Mf|Mf]] 11:39, 27 April 2012 (UTC)). Would like to hack a SPKI C-binding and high-level PKI API.<br />
<br />
<br />
== Agenda ==<br />
<br />
I have more than enough ideas for projects, but please everybody propose your own. I am more than happy to step back and do something you think is relevant. If you want to attend, please leave a note which projects you are most interested in.<br />
<br />
<br />
=== Implement SPKI ===<br />
<br />
Since SSL/TLS is notoriously convoluted and error prone (most recent evidence: http://lists.grok.org.uk/pipermail/full-disclosure/2012-April/086585.html), it may be time to make another effort to replace it. SPKI addresses many requirements that SSL/TLS does, but is much more concise and coherent.<br />
<br />
* Overview: http://world.std.com/~cme/html/spki.html<br />
* Standards: http://world.std.com/~cme/spki.txt, http://www.ietf.org/rfc/rfc2693.txt<br />
* Algorithms: Distributed Credential Chain in Trust Management, Proceedings of the 8th ACM Conference on Computer and Communications Security (CCS-8), pages 156–165, ACM Press, November 2001.<br />
<br />
The idea of this one is not so much to make something new, but to take something that is done in a language different from Haskell, and see how well it ports. This will not only give us a deeper understanding of both source and target language, but also make it more convenient to build applications in Haskell, and through interop testing will lead to better code in the original implementation as well.<br />
<br />
Variants: Take one of the implementations and build a C binding. Design an abstract PKI API that can be used to manipulate both x509/SSL and SPKI credentials. Implement a mapping between x509/SSL and SPKI credentials.<br />
<br />
<br />
=== Port ZooKeeper to Haskell ===<br />
<br />
* http://wiki.apache.org/hadoop/ZooKeeper<br />
<br />
Zookeeper is the distributed key/value store used for synchronisation in Hadoop, but intended for a much larger application space. A lot of skill and effort has gone into the design, implementation and testing, and it solves problems that all distributed applications have. I like this project.<br />
<br />
It would be totally hot if there was a Haskell implementation that could outperform the Apache Foundation's Java implementation. That is not a two-weekend project, but a ghc binding might be.<br />
<br />
<br />
=== Implement Kademlia in Haskell ===<br />
<br />
* Research paper explaining the algorithm: http://www.cs.rice.edu/Conferences/IPTPS02/109.pdf<br />
* Python implementation: http://entangled.sourceforge.net/<br />
<br />
Again: This could be done as a port, a binding, or a complete re-implementation.<br />
<br />
<br />
=== Play with adhocracy, liquid feedback, ... ===<br />
<br />
These are tools to help organize participatory and open political processes.<br />
<br />
* http://translate.google.ch/translate?sl=de&tl=en&js=n&prev=_t&hl=de&ie=UTF-8&layout=2&eotf=1&u=http%3A%2F%2Fde.wikipedia.org%2Fwiki%2FAdhocracy_%2528Software%2529<br />
* http://lists.liqd.net/cgi-bin/mailman/listinfo/adhocracy-dev<br />
* http://translate.google.ch/translate?hl=de&sl=de&tl=en&u=http%3A%2F%2Fde.wikipedia.org%2Fwiki%2FLiquidFeedback<br />
<br />
These are two projects I am curious about, but have not had to the time to look into. I know that one of them is running on adequate development resources, so if anybody is interested in this we could probably ask the project owners for challenges and chores.</div>Shahnhttps://wiki.haskell.org/index.php?title=Hac_%CF%86/Attendees&diff=40972Hac φ/Attendees2011-07-13T20:16:08Z<p>Shahn: /* Attendees in Berlin */ added shahn</p>
<hr />
<div>This is a partial list of attendees for [[Hac φ]]. Please refer to the [[Hac φ|main page]] for more information.<br />
<br />
= Attendees =<br />
<br />
Feel free to list yourself here -- though this is ''not'' registration. To register, see [[Hac φ/Register|this page]].<br />
<br />
{| class="wikitable"<br />
! Nickname<br />
! Real Name<br />
! Mobile #<br />
! Arriving<br />
! Departing<br />
! Accommodation<br />
|-<br />
| byorgey<br />
| Brent Yorgey<br />
| (202)-531-8646<br />
| -<br />
| -<br />
| lives in Philadelphia<br />
|-<br />
| dmwit<br />
| Daniel Wagner<br />
| (650)-353-1788<br />
| -<br />
| -<br />
| lives in Philadelphia<br />
|-<br />
| ccasin<br />
| Chris Casinghino<br />
| (603) 860-5301<br />
| -<br />
| -<br />
| lives in Philadelphia<br />
|-<br />
| ymasory<br />
| Yuvi Masory<br />
| ymasory@gmail.com<br />
| -<br />
| -<br />
| lives in Philadelphia, can host one guest for two nights (update: spots are taken).<br />
|-<br />
| yrlnry<br />
| [[Mark Dominus]]<br />
| mjd@plover.com<br />
| -<br />
| -<br />
| lives in Philadelphia<br />
|-<br />
| amindfv<br />
| Tom Murphy<br />
| amindfv@gmail.com<br />
| Thurs or Fri<br />
| Sunday<br />
| Found<br />
|-<br />
| fryguybob<br />
| Ryan Yates<br />
| fryguybob@gmail.com<br />
| Fri<br />
| Sunday<br />
| Unknown<br />
|-<br />
| copumpkin<br />
| Dan Peebles<br />
| (603) 738-1570<br />
| Unsure<br />
| Unsure<br />
| Unsure<br />
|-<br />
| brweber2<br />
| Bryan Weber<br />
| brweber2 yahoo<br />
| Fri<br />
| Sunday<br />
| done<br />
|- <br />
| lpsmith<br />
| Leon P Smith<br />
| leon.p.smith@gmail.com<br />
| Fri<br />
| Sun<br />
| done<br />
|-<br />
| jmcarthur<br />
| Jake McArthur<br />
| Jake.McArthur@gmail.com<br />
| Fri<br />
| Sunday<br />
| unknown<br />
|-<br />
| acowley<br />
| Anthony Cowley<br />
| acowley@seas.upenn.edu<br />
| -<br />
| -<br />
| Jersey, New<br />
|- <br />
| thoughtpolice<br />
| Austin Seipp<br />
| as@hacks.yi.org<br />
| Fri<br />
| Sunday<br />
| unknown<br />
|-<br />
| dankna<br />
| Dan Knapp<br />
| dankna@gmail.com<br />
| Fri<br />
| Sun<br />
| With family<br />
|-<br />
| ludflu<br />
| Jim Snavely<br />
| ludflu@gmail.com<br />
| Sat<br />
| ?<br />
| Lives in philadelphia<br />
|-<br />
| swalck<br />
| Scott Walck<br />
| walck@lvc.edu<br />
| Fri<br />
| Sun<br />
| Club Quarters<br />
|-<br />
| djahandarie<br />
| Darius Jahandarie<br />
| djahandarie at gmail<br />
| ?<br />
| ?<br />
| ¯\(°_0)/¯<br />
|-<br />
| mightybyte<br />
| Doug Beardsley<br />
| <nickname> at gmail<br />
| <br />
| <br />
| unsure<br />
|-<br />
|}<br />
<br />
<br />
<br />
== Attendees in Berlin ==<br />
<br />
{| class="wikitable"<br />
! Nickname<br />
! Real Name<br />
! Mobile #<br />
! Arriving<br />
! Departing<br />
! Accommodation<br />
|-<br />
| <br />
| Matthias Fischmann<br />
| +49 179 7733223 / m.fischmann at gmail<br />
| Fri <br />
| Sun<br />
| <br />
|-<br />
|<br />
| Daniel van den Eijkel<br />
| dvde at gmx dot net<br />
| Fri<br />
| Sun<br />
|<br />
|-<br />
|<br />
| Sönke Hahn<br />
| shahn at cs.tu-berlin.de<br />
| Fri<br />
| Sun<br />
| lives in Berlin<br />
|}<br />
<br />
= Additional Comments =<br />
<br />
Please use this section to leave comments for other attendees, e.g. for organizing accommodation.<br />
<br />
I'm an undergraduate student doing research this summer. I'm very interested in attending, but I doubt I could afford a hotel, so if anyone in Philly has a place I could stay please let me know. [[User:FmapE|FmapE]] 03:31, 16 June 2011 (UTC)</div>Shahnhttps://wiki.haskell.org/index.php?title=Hp2any&diff=34024Hp2any2010-03-12T15:18:05Z<p>Shahn: </p>
<hr />
<div>== Overview ==<br />
<br />
The name hp2any covers a set of tools and libraries to deal with heap profiles of Haskell programs. At the present moment, the project consists of three packages:<br />
<br />
* [http://hackage.haskell.org/package/hp2any-core hp2any-core]: a library offering functions to read heap profiles during and after run, and to perform queries on them.<br />
* [http://hackage.haskell.org/package/hp2any-graph hp2any-graph]: an OpenGL-based live grapher that can show the memory usage of local and remote processes (the latter using a relay server included in the package), and a library exposing the graphing functionality to other applications.<br />
* [http://hackage.haskell.org/package/hp2any-manager hp2any-manager]: a GTK application that can display graphs of several heap profiles from earlier runs.<br />
<br />
The project is maintained by [[User:GergelyPatai|Patai Gergely]]. There is a [http://code.google.com/p/hp2any/ Google Code source repository] where you can track changes. If you are interested in contributing, you can reach me at <patai@iit.bme.hu>.<br />
<br />
== hp2any-core ==<br />
<br />
The package comes with detailed Haddock commentary. The modules exposed are the following in decreasing order of importance:<br />
<br />
* Profiling.Heap.Types: the commonly used data structures and basic types of the framework.<br />
* Profiling.Heap.Read: the functions to load .hp files and to initiate live profiling.<br />
* Profiling.Heap.Stats: a data structure to efficiently query statistics over time intervals.<br />
* Profiling.Heap.Process: a helper module to construct CreateProcess structures for the profiling functions.<br />
* Profiling.Heap.Network: a messaging module providing serialisation for profiling related information (used by the remote profiler).<br />
<br />
A simple example to get the peak of the memory usage from an old run:<br />
<br />
<haskell><br />
import Profiling.Heap.Read<br />
import Profiling.Heap.Types<br />
<br />
main = do<br />
mprof <- readProfile "myprog.hp"<br />
case mprof of<br />
Nothing -> putStrLn "Couldn't read heap profile!"<br />
Just prof -> putStrLn $ "Maximum residency: " ++ show (maxCostTotal prof) ++ " bytes."<br />
</haskell><br />
<br />
If you want to make several queries like that, using the Stats module can pay off. It offers the ProfileWithStats data structure, which can be queried using the same ProfileQuery interface as the much simpler Profile structure, which is optimised for loading and incremental accumulation.<br />
<br />
Performing live profiling is similarly simple. If you want to create a simple profile logger, you can do something like the following:<br />
<br />
<haskell><br />
import Control.Concurrent<br />
import Profiling.Heap.Process<br />
import Profiling.Heap.Read<br />
import Profiling.Heap.Types<br />
<br />
main = do<br />
let proc = processToProfile "./myprog" Nothing ["-param1","-param2"] [PPBreakdown BCostCentreStack,PPInterval 0.1]<br />
pcres <- profileCallback (Local proc) print<br />
case pcres of<br />
Nothing -> putStrLn "Something bad happened."<br />
Just (stopReading,Local hdl) -> do<br />
putStrLn "Streaming heap profile for 10 seconds:"<br />
threadDelay 10000000<br />
stopReading<br />
</haskell><br />
<br />
This starts up a slave process and kills the profile reading thread after 10 seconds. However, it doesn’t kill the process itself; you can do that given its handle. Note the "./" in front of the program name. The library will not take care of finding out whether you want to run a program in the current directory, since you might need that distinction. To make this cross-platform, it is advisable to pass this string to System.FilePath.canonicalizePath, since Windows might have problems with prepended "./".<br />
<br />
Note that the callback is invoked in a different thread, so if you need to be in the main thread (e.g. if using various widget toolkits), you’ll have to use communication primitives like MVar to get the information to the place where you want it.<br />
<br />
== hp2any-graph ==<br />
<br />
The package includes two programs: hp2any-graph and hp2any-relay. The former can be used to start up a process to profile and display its heap usage on the fly using OpenGL. Alternatively, it can also connect to a hp2any-relay instance running on a remote host. The relay server is used essentially the same way as the grapher, but instead of opening a window, it opens a server socket and starts streaming the heap profile of its associated process to whomever connects to it.<br />
<br />
The following sections show you how to use these tools. First of all, let’s create this simple test application in heaptest.hs:<br />
<br />
<haskell><br />
import Text.Printf<br />
<br />
main :: IO ()<br />
main = exercise 500000<br />
<br />
exercise :: Double -> IO ()<br />
exercise d = do<br />
printf "Input: %f\n" d<br />
printf "Result: %f\n" (mean [1..d])<br />
exercise (d*1.5)<br />
<br />
mean :: [Double] -> Double<br />
mean xs = sum xs / fromIntegral (length xs)<br />
</haskell><br />
<br />
Calculating the mean this way forces the whole list to be in the memory at the same time, since we are calculating its sum and length separately. Since the lists are getting longer with each iteration, we’ll eventually run into a stack overflow.<br />
<br />
=== Compilation ===<br />
<br />
In order to get a heap profile out of a program, we have to compile it with some profiling options:<br />
<br />
ghc --make heaptest -O2 -prof -auto-all<br />
<br />
In short, the -prof option enables profiling, while -auto-all instruments the executable by putting a cost centre (a named point of measurement) at every top-level declaration. If you want more fine-grained heap profiles, you can put SCC pragmas at any expression within the program. Consult the [http://www.haskell.org/ghc/docs/latest/html/users_guide/profiling.html documentation of GHC] for further details.<br />
<br />
=== Local profiling ===<br />
<br />
Local profiling is simple: just invoke the program through hp2any-graph and pass it the necessary parameters:<br />
<br />
hp2any-graph -e heaptest -- +RTS -hc -K100M -i0.02<br />
<br />
Everything after the -- is passed to the slave process as command line parameter. In this case, we are passing profiling related parameters to the runtime (+RTS). In particular, we ask for a heap profile by cost centre stack (-hc), set a big stack so the program can keep running for a little while (-K), and set a profile sample rate that’s higher than the default (-i).<br />
<br />
Don’t be surprised if the animation is not smooth, as the heap profile might be aggressively buffered by the operating system. When a program is more complex and there are more active cost centres, one can see the samples almost as they are produced. That’s also the reason to increase the sampling rate for this small example.<br />
<br />
=== Remote profiling ===<br />
<br />
In order to access the heap profile of a remote process, we need a server that relays the information to the grapher. This is essentially the same as above, except we use hp2any-relay and also specify a port number to listen on:<br />
<br />
hp2any-relay -p 5678 -e heaptest -- +RTS -hc -K100M -i0.02<br />
<br />
We can connect to such a relay by starting the grapher in remote mode, where we only give it a server address:<br />
<br />
hp2any-graph -s localhost:5678<br />
<br />
It is possible to attach several viewers to the same relay at the same time. Each grapher sees only the samples produced after it was attached.<br />
<br />
=== Viewing later ===<br />
<br />
The grapher is not capable of viewing heap profiles of processes that already finished. The history manager (hp2any-manager, in a separate package) takes care of that duty, providing a much more comfortable interface. <br />
<br />
== hp2any-manager ==<br />
<br />
The history manager is a simple application that can display heap profiles of Haskell programs. Graphs are arranged like in a tiling window manager. Here’s a screenshot to give you an idea (click for higher resolution):<br />
<br />
[[Image:Hp2any-manager.png|800px|The hp2any interface.]]<br />
<br />
The main window is divided into columns, and each column can hold several graphs. New columns can be added with the + button on the right hand side, while each column can be closed with its respective Close button at the top.<br />
<br />
Heap profiles can be loaded by clicking the Open button at the bottom of the column we want them to appear in. The open dialog has multi-selection enabled. If more than one .hp file is selected, all of them will be loaded in the same column.<br />
<br />
Each graph has a header with some buttons. The first button brings up a menu with some viewing options, the second and third can be used to move the graph to neighbouring columns, and the last one closes the file. Graphs can be zoomed in and out using the mouse wheel, and navigated using the scroll bar below them. The view is automatically zoomed to fit the highest point of the graph section shown. The actual coordinates are shown on a tooltip.<br />
<br />
Besides the graph, every profile window shows a list of cost centres. The list can be reordered according to the total cost by clicking on the header of the second column. As the mouse moves over the graph, the corresponding item is highlighted in the list. The colour black does not correspond to a single cost centre in the list. It is used for (the sum of) costs below a certain value (256?).<br />
<br />
== Future work ==<br />
<br />
The project also aims at replacing hp2ps by reimplementing it in Haskell and possibly adding new output formats. The manager application shall be extended to display and compare the graphs in more ways, to export them in other formats and also to support live profiling right away instead of delegating that task to hp2any-graph.</div>Shahnhttps://wiki.haskell.org/index.php?title=Sandbox&diff=34004Sandbox2010-03-10T13:07:12Z<p>Shahn: </p>
<hr />
<div>''Feel free to edit as you wish on this page. It is here for you to experiment with WIKI edit syntax.''<br />
==section==<br />
[[Sandbox#secton]]<br><br />
<br />
<br />
<br />
--[[User:Lars|Lars]] 11:14, 27 July 2009 (UTC)<br />
----<br />
<math>Insert formula here</math>[[Media:Example.ogg]][[Image:Example.jpg]]<br />
== Headline text ==<br />
''Italic text'''''Bold text'''<br />
{| border="1"<br />
|-<br />
|Pavillon || Uge || Uge <br />
|}<br />
<br />
Matrix:<br />
:<math>\left[ \begin{matrix}1 & 2 \\ 3 & 4\end{matrix} \right]</math><br />
<br />
Embedded matrix:<br />
:<math>\left[ \begin{matrix}1 & 2 \\ 3 & \left[ \begin{matrix}5 & 6 \\ 7 & 8\end{matrix}\right] \end{matrix} \right]</math><br />
<br />
http://cs.pdx.edu/<br />
:<br />
http://cs.pdx.edu/~dick/HaskellSemantics/jpf05.pdf<br />
:<br />
http://cs.pdx.edu/~dick/HaskellSemantics/Haskell98.pdf<br />
<br />
Text taken from http://hpaste.org/3881: this wiki's syntax highlight at least does not garble the source, unlike hpaste's highlight.<br />
<br />
<haskell><br />
module Main where<br />
<br />
import Prelude hiding (putStrLn, print)<br />
import System.IO.UTF8<br />
import Data.List (intersperse, find)<br />
<br />
type Персонаж = String<br />
type Персонажи = [Персонаж]<br />
<br />
едоки :: Персонажи<br />
едоки = [ "дедка", "бабка", "внучка", "жучка", "кошка", "мышка" ]<br />
<br />
подходы :: [ Персонажи ]<br />
подходы = scanl позвать [] едоки<br />
where позвать тянущие подмога = подмога:тянущие<br />
<br />
построились :: Персонажи -> [ (Персонаж, Персонаж) ]<br />
построились едоки = zip едоки ("репка":едоки)<br />
<br />
диспозиции = map (построились.reverse) подходы<br />
<br />
описать [] = "Посадил дед репку ..."<br />
описать диспозиция = <br />
unwords ["Взялись:"<br />
, concat $ intersperse ", " $ map за диспозиция<br />
, ". Тянут-потянут -- " ++ result<br />
]<br />
where <br />
за (кто,кого) = кто ++ " за " ++ винительный_падеж кого<br />
винительный_падеж ы = init ы ++ "у"<br />
result = case find ((=="мышка").fst) диспозиция of<br />
Just _ -> "вытянули репку!"<br />
Nothing -> "вытянуть не могут!"<br />
<br />
main = mapM_ putStrLn $ map описать диспозиции</haskell><br />
<br />
== Section ==<br />
=== Subsection ===<br />
==== Subsubsection ====<br />
<br />
huhu<br />
<br />
===== Subsubsubsection =====</div>Shahnhttps://wiki.haskell.org/index.php?title=Applications_and_libraries/Music_and_sound&diff=16156Applications and libraries/Music and sound2007-10-14T15:08:34Z<p>Shahn: </p>
<hr />
<div>{{LibrariesPage}}<br />
<br />
== Applications ==<br />
<br />
;[http://www.cse.unsw.edu.au/~dons/hmp3.html hmp3]<br />
:hmp3 is a curses-based mp3 player frontend to mpg321 and mpg123. It is written in Haskell. It is designed to be simple, fast and robust. It's very stable, with one instance running for several months.<br />
<br />
;[http://urchin.earth.li/darcs/ian/minstrel/ minstrel]<br />
:Minstrel is a curses frontend to the GStreamer library written in Haskell.<br />
<br />
;[http://www.lintao.org/repos/hxine hxine]<br />
:A console frontend to the xine library<br />
<br />
;[http://www.annodex.net/~conrad/software/hogg.html HOgg]<br />
:A library for handling the Ogg container format. Note that this just deals with the Ogg container, not with the contained Vorbis audio or Theora video etc. Includes a commandline tool (hogg) for querying files, merging and ripping tracks, hexdumping packets and pages and so on.<br />
<br />
=== Music composition ===<br />
<br />
;[http://haskell.org/haskore/ The Haskore Computer Music System]<br />
:Haskore is a collection of Haskell modules designed for expressing musical structures in the high-level, declarative style of functional programming. Haskore is a means for describing music - in particular Western Music - rather than sound. It is not a vehicle for synthesizing sound produced by musical instruments, for example, although it does capture the way certain (real or imagined) instruments permit control of dynamics and articulation. Haskore compositions can be translated into various audible formats like MIDI, CSound and SuperCollider. (Former versions in LISP could generate traditional notation output, but this is currently not available in the Haskell version.)<br />
<br />
;[[Haskore]] related projects<br />
<br />
;[http://meltin.net/hacks/haskell/ HasChorus]<br />
:A set of Haskell modules written on top of Haskore to make it easier to sequence simple, repetitive music.<br />
<br />
== Libraries ==<br />
<br />
;HOpenAL<br />
:A Haskell Binding for OpenAL and ALUT. The goal of this project is to provide a binding for OpenAL, a cross-platform 3D audio API, appropriate for use with gaming applications and many other types of audio applications.<br />
<br />
;[http://darcs.haskell.org/~lemmih/hsSDL/ hsSDL]<br />
:Contains bindings to libSDL, libSDL_gfx, libSDL_image, libSDL_mixer and libSDL_ttf.<br />
<br />
;[http://haskelldsp.sourceforge.net/ HaskellDSP]<br />
:Signal processing coded in Haskell. Contains also some matrix and stochastic computations which are required for signal processing.<br />
:Now managed with [http://darcs.haskell.org/dsp/ darcs repository], shipped via [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/dsp Hackage].<br />
<br />
;[http://open-projects.net/~shahn/index.php?seite=code JACK an ALSA wrapper], both in a very early stage.<br />
<br />
;[http://www.slavepianos.org/rd/f/207949/ SuperCollider]<br />
:Interface to the realtime software synthesizer [http://www.audiosynth.com/ SuperCollider]. Experimental. Includes widely useful [http://cnmat.berkeley.edu/OpenSoundControl/ OpenSoundControl] module.<br />
<br />
;[http://darcs.haskell.org/synthesizer/ Synthesizer library]<br />
:Signal processing related to audio effects coded in plain Haskell. There is both a low-level interface and a framework for automatical inference of sample rate and amplitude of signals in a sound processing network. This generalizes the usual restricted splitting into audio rate and control rate signals. There is an interface for using synthesized sounds for rendering [[Haskore]] music. Recent versions require [http://darcs.haskell.org/numericprelude/ NumericPrelude]. Highly experimental.<br />
<br />
;[http://www.student.nada.kth.se/~alfonsoa/HLADSPA/ HLADPSA]<br />
:A port of [http://www.ladspa.org/ LADSPA] (Linux Audio Developer's Simple Plugin API) to Haskell. Still highly experimental. The project can be regarded as an example of how to create plugins and shared libraries in Haskell without making use of [http://www.cse.unsw.edu.au/~dons/hs-plugins/ hs-plugins].<br />
<br />
;[http://mcs.une.edu.au/~bsinclai/code/libmpd-haskell.html MPD client library]<br />
:A client library for controlling an MPD server.<br />
== Hackage==<br />
<br />
* [http://hackage.haskell.org/packages/archive/pkg-list.html#cat:Sound Sound libraries on Hackage]<br />
<br />
[[Category:Music]]</div>Shahnhttps://wiki.haskell.org/index.php?title=Applications_and_libraries/Music_and_sound&diff=12468Applications and libraries/Music and sound2007-04-09T17:06:14Z<p>Shahn: </p>
<hr />
<div>{{LibrariesPage}}<br />
<br />
== Applications ==<br />
<br />
;[http://www.cse.unsw.edu.au/~dons/hmp3.html hmp3]<br />
:hmp3 is a curses-based mp3 player frontend to mpg321 and mpg123. It is written in Haskell. It is designed to be simple, fast and robust. It's very stable, with one instance running for several months.<br />
<br />
;[http://urchin.earth.li/darcs/ian/minstrel/ minstrel]<br />
:Minstrel is a curses frontend to the GStreamer library written in Haskell.<br />
<br />
;[http://www.lintao.org/repos/hxine hxine]<br />
:A console frontend to the xine library<br />
<br />
;[http://www.annodex.net/~conrad/software/hogg.html HOgg]<br />
:A library for handling the Ogg container format. Note that this just deals with the Ogg container, not with the contained Vorbis audio or Theora video etc. Includes a commandline tool (hogg) for querying files, merging and ripping tracks, hexdumping packets and pages and so on.<br />
<br />
=== Music composition ===<br />
<br />
;[http://haskell.org/haskore/ The Haskore Computer Music System]<br />
:Haskore is a collection of Haskell modules designed for expressing musical structures in the high-level, declarative style of functional programming. Haskore is a means for describing music - in particular Western Music - rather than sound. It is not a vehicle for synthesizing sound produced by musical instruments, for example, although it does capture the way certain (real or imagined) instruments permit control of dynamics and articulation. Haskore compositions can be translated into various executable formats like MIDI and printed in traditional notation.<br />
<br />
;[[Haskore]] related projects<br />
<br />
;[http://meltin.net/hacks/haskell/ HasChorus]<br />
:A set of Haskell modules written on top of Haskore to make it easier to sequence simple, repetitive music.<br />
<br />
== Libraries ==<br />
<br />
;HOpenAL<br />
:A Haskell Binding for OpenAL and ALUT. The goal of this project is to provide a binding for OpenAL, a cross-platform 3D audio API, appropriate for use with gaming applications and many other types of audio applications.<br />
<br />
;[http://darcs.haskell.org/~lemmih/hsSDL/ hsSDL]<br />
:Contains bindings to libSDL, libSDL_gfx, libSDL_image, libSDL_mixer and libSDL_ttf.<br />
<br />
;[http://haskelldsp.sourceforge.net/ HaskellDSP]<br />
:Signal processing coded in Haskell. Contains also some matrix and stochastic computations which are required for signal processing.<br />
<br />
;[http://open-projects.net/~shahn/index.php?seite=code JACK wrapper], very early stage.<br />
<br />
;[http://www.slavepianos.org/rd/f/207949/ SuperCollider]<br />
:Interface to the realtime software synthesizer [http://www.audiosynth.com/ SuperCollider]. Experimental. Includes widely useful [http://cnmat.berkeley.edu/OpenSoundControl/ OpenSoundControl] module.<br />
<br />
;[http://darcs.haskell.org/synthesizer/ Synthesizer library]<br />
:Signal processing related to audio effects coded in plain Haskell. There is both a low-level interface and a framework for automatical inference of sample rate and amplitude of signals in a sound processing network. This generalizes the usual restricted splitting into audio rate and control rate signals. There is an interface for using synthesized sounds for rendering [[Haskore]] music. Recent versions require [http://darcs.haskell.org/numericprelude/ NumericPrelude]. Highly experimental.<br />
<br />
;[http://www.student.nada.kth.se/~alfonsoa/HLADSPA/ HLADPSA]<br />
:A port of [http://www.ladspa.org/ LADSPA] (Linux Audio Developer's Simple Plugin API) to Haskell. Still highly experimental. The project can be regarded as an example of how to create plugins and shared libraries in Haskell without making use of [http://www.cse.unsw.edu.au/~dons/hs-plugins/ hs-plugins].<br />
<br />
[[Category:Music]]</div>Shahnhttps://wiki.haskell.org/index.php?title=Applications_and_libraries/Music_and_sound&diff=12467Applications and libraries/Music and sound2007-04-09T17:04:42Z<p>Shahn: </p>
<hr />
<div>{{LibrariesPage}}<br />
<br />
== Applications ==<br />
<br />
;[http://www.cse.unsw.edu.au/~dons/hmp3.html hmp3]<br />
:hmp3 is a curses-based mp3 player frontend to mpg321 and mpg123. It is written in Haskell. It is designed to be simple, fast and robust. It's very stable, with one instance running for several months.<br />
<br />
;[http://urchin.earth.li/darcs/ian/minstrel/ minstrel]<br />
:Minstrel is a curses frontend to the GStreamer library written in Haskell.<br />
<br />
;[http://www.lintao.org/repos/hxine hxine]<br />
:A console frontend to the xine library<br />
<br />
;[http://www.annodex.net/~conrad/software/hogg.html HOgg]<br />
:A library for handling the Ogg container format. Note that this just deals with the Ogg container, not with the contained Vorbis audio or Theora video etc. Includes a commandline tool (hogg) for querying files, merging and ripping tracks, hexdumping packets and pages and so on.<br />
<br />
=== Music composition ===<br />
<br />
;[http://haskell.org/haskore/ The Haskore Computer Music System]<br />
:Haskore is a collection of Haskell modules designed for expressing musical structures in the high-level, declarative style of functional programming. Haskore is a means for describing music - in particular Western Music - rather than sound. It is not a vehicle for synthesizing sound produced by musical instruments, for example, although it does capture the way certain (real or imagined) instruments permit control of dynamics and articulation. Haskore compositions can be translated into various executable formats like MIDI and printed in traditional notation.<br />
<br />
;[[Haskore]] related projects<br />
<br />
;[http://meltin.net/hacks/haskell/ HasChorus]<br />
:A set of Haskell modules written on top of Haskore to make it easier to sequence simple, repetitive music.<br />
<br />
== Libraries ==<br />
<br />
;HOpenAL<br />
:A Haskell Binding for OpenAL and ALUT. The goal of this project is to provide a binding for OpenAL, a cross-platform 3D audio API, appropriate for use with gaming applications and many other types of audio applications.<br />
<br />
;[http://darcs.haskell.org/~lemmih/hsSDL/ hsSDL]<br />
:Contains bindings to libSDL, libSDL_gfx, libSDL_image, libSDL_mixer and libSDL_ttf.<br />
<br />
;[http://haskelldsp.sourceforge.net/ HaskellDSP]<br />
:Signal processing coded in Haskell. Contains also some matrix and stochastic computations which are required for signal processing.<br />
<br />
;[http://open-projects.net/~shahn/index.php?seite=code JACK wrapper]<br />
<br />
;[http://www.slavepianos.org/rd/f/207949/ SuperCollider]<br />
:Interface to the realtime software synthesizer [http://www.audiosynth.com/ SuperCollider]. Experimental. Includes widely useful [http://cnmat.berkeley.edu/OpenSoundControl/ OpenSoundControl] module.<br />
<br />
;[http://darcs.haskell.org/synthesizer/ Synthesizer library]<br />
:Signal processing related to audio effects coded in plain Haskell. There is both a low-level interface and a framework for automatical inference of sample rate and amplitude of signals in a sound processing network. This generalizes the usual restricted splitting into audio rate and control rate signals. There is an interface for using synthesized sounds for rendering [[Haskore]] music. Recent versions require [http://darcs.haskell.org/numericprelude/ NumericPrelude]. Highly experimental.<br />
<br />
;[http://www.student.nada.kth.se/~alfonsoa/HLADSPA/ HLADPSA]<br />
:A port of [http://www.ladspa.org/ LADSPA] (Linux Audio Developer's Simple Plugin API) to Haskell. Still highly experimental. The project can be regarded as an example of how to create plugins and shared libraries in Haskell without making use of [http://www.cse.unsw.edu.au/~dons/hs-plugins/ hs-plugins].<br />
<br />
[[Category:Music]]</div>Shahn