Creating polymorphic functions in Haskell

A short search did not help me find the answer, so I began to doubt its existence. Quests are simple: I want to create a polymorphic function, something like this:

f :: String -> String fs = show (length s) f :: Int -> String fi = show i 

A function is defined that is defined differently for different types. Is it possible, and how?

+4
source share
2 answers

Haskell has two options for polymorphism:

  • parametric polymorphism; and
  • limited polymorphism

The first is the most general - a function is parametrically polymorphic if it behaves uniformly for all types, at least in one of its type parameters.

For example, the length function is polymorphic - it returns the length of the list, regardless of what type is stored in its list.

 length :: [a] -> Int 

Polymorphism is denoted by a variable of the lower case type.

Now, if you have custom behavior that you want to have for a specific set of types, then you have limited polymorphism (also known as "ad hoc"). At Haskell, we use type classes for this.

The class declares which function will be available on a set of types:

 class FunnyShow a where funnyshow :: a -> String 

and then you can define instances for each type you care about:

 instance FunnyShow Int where funnyshow i = show (i+1) 

and, perhaps:

 instance FunnyShow [Char] where funnyshow s = show (show s) 
+14
source

Here's how you can achieve something similar using type families.

Well, if you have the same return types, you can achieve behavior without using type families and just use type classes, as suggested by don.

But it's better to use type families if you want to support more complex adhoc polymorphism, for example different return types for each instance.

 {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE TypeSynonymInstances #-} {-# LANGUAGE TypeFamilies #-} class F a where type Out a :: * f :: a -> Out a instance F String where type Out String = String f = show . length instance F Int where type Out Int = String f = show instance F Float where type Out Float = Float f = id 

In ghci

 *Main> f (2::Int) "2" *Main> f "Hello" "5" *Main> f (2::Float) 2.0 
+7
source

Source: https://habr.com/ru/post/1434283/


All Articles