haskell - Why encode function in data type definition? -


i find hard intuition encoding function in data type definition. done in definition of state , io types, e.g.

data state s = state s -> (a,s) type io = realworld -> (a, realworld) -- type synonym though, not new type 

i see more trivial example understand value possibly build on have more complex examples. e.g. have data structure, make sense encode function in 1 of data constructor.

data tree = node int (tree) (tree) (? -> ?) | e 

i not sure trying here, example of function can encode in such type? , why have encode in type, not use normal function, don't know, maybe passed argument when needed?

really, functions data else.

prelude> :i (->)
data (->) b -- defined in`ghc.prim'
instance monad ((->) r) -- defined in`ghc.base'
instance functor ((->) r) -- defined in`ghc.base'

this comes out naturally , without conceptually surprising if consider functions from, say, int. i'll give them strange name: (remember (->) b means a->b)

type array = (->) int 

what? well, what's important operation on array?

prelude> :t (data.array.!)
(data.array.!) :: ghc.arr.ix => ghc.arr.array e -> -> e
prelude> :t (data.vector.!)
(data.vector.!) :: data.vector.vector -> int -> a

let's define our own array type:

(!) :: array -> int -> (!) = ($) 

now can do

test :: array string test 0 = "bla" test 1 = "foo" 

fnarray> test ! 0
"bla"
fnarray> test ! 1
"foo"
fnarray> test ! 2
"*** exception: :8:5-34: non-exhaustive patterns in function test

compare to

prelude data.vector> let test = fromlist ["bla", "foo"]
prelude data.vector> test ! 0
"bla"
prelude data.vector> test ! 1
"foo"
prelude data.vector> test ! 2
"*** exception: ./data/vector/generic.hs:244 ((!)): index out of bounds (2,2)

not different, right? it's haskell's enforcement of referential transparency guarantees return values of function can interpreted inhabitant values of container. 1 common way @ functor instance: fmap transform f applies transformation values "included" in f (as result values). works composing transformation after target function:

instance functor (r ->)   fmap transform f x = transform $ f x 

(though you'd of course better write fmap = (.).)


now, what's bit more confusing (->) type constructor has 1 more type argument: argument type. let's focus on defining

{-# language typeoperators #-}  newtype (:<-) b = backfunc (b->a) 

to feel it:

show' :: show  =>  string :<- show' = backfunc show 

i.e. it's function arrows written other way around.

is (:<-) int sort of container, how (->) int resembles array? not quite. can't define instance functor (a :<-). yet, mathematically speaking, (a :<-) is functor, of different kind: contravariant functor.

instance contravariant (a :<-)   contramap transform (backfunc f) = backfunc $ f . transform 

"ordinary" functors otoh covariant functors. naming rather easy understand if compare directly:

fmap      :: functor f       => (a->b) -> f a->f b contramap :: contravariant f => (b->a) -> f a->f b 

while contravariant functors aren't commonly used covariant ones, can use them in same way when reasoning data flow etc.. when using functions in data fields, it's covariant vs. contravariant should foremostly think about, not functions vs. values – because really, there nothing special functions compared "static values" in purely functional language.


about tree type

i don't think data type made really useful, can stupid similar type may illustrate points made above:

data tree' = node int (bool -> tree) | e 

that is, disconsidering performance, isomorphic usual

data tree = node int tree tree | e 

why? well, bool -> tree similar array tree, except don't use ints indexing bools. , there 2 evaluatable boolean values. arrays fixed size 2 called tuples. , bool->tree ≅ (tree, tree) have node int (bool->tree) ≅ node int tree tree.

admittedly isn't interesting. functions fixed domain isomorphism obvious. interesting cases polymorphic on function domain and/or codomain, leads abstract results such state monad. in cases, can remember nothing seperates functions other data types in haskell.


Comments

Popular posts from this blog

Detect support for Shoutcast ICY MP3 without navigator.userAgent in Firefox? -

web - SVG not rendering properly in Firefox -

java - JavaFX 2 slider labelFormatter not being used -