typeclass - How should types be used in Haskell type classes? -


i'm new haskell, , little confused how type classes work. here's simplified example of i'm trying do:

data listofints = listofints {value :: [int]} data listofdoubles = listofdoubles {value :: [double]}  class incrementable     increment :: ->  instance incrementable listofints     increment ints = map (\x -> x + 1) ints  instance incrementable listofdoubles     increment doubles = map (\x -> x + 1) doubles 

(i realize incrementing each element of list can done simply, simplified version of more complex problem.)

the compiler tells me have multiple declarations of value. if change definitions of listofints , listofdoubles follows:

type listofints = [int] type listofdoubles = [double] 

then compiler says "illegal instance declaration 'incrementable listofints'" (and listofdoubles. if use newtype, e.g., newtype listofints = listofints [int], compiler tells me "couldn't match expected type 'listofints' actual type '[b0]'" (and listofdoubles.

my understanding of type classes facilitate polymorphism, i'm missing something. in first example above, compiler see type parameter a refers record field called value , appears i'm trying define increment type in multiple ways (rather seeing 2 different types, 1 has field type of list of ints, , other type list of doubles)? , other attempts?

thanks in advance.

you're seeing 2 separate problems, i'll address them such.

the first 1 value field. haskell records work in peculiar way: when name field, automatically added current scope function. essentially, can think of

data listofints = listofints {value :: [int]} 

as syntax sugar for:

data listofints = listofints [int]  value :: listofint -> [int] value (listofints v) = v 

so having two records same field name having 2 different functions same name--they overlap. why first error tells you've declared values multiple times.

the way fix define types without using record syntax, did above:

data listofints = listofints [int] data listofdoubles = listofdoubles [double] 

when used type instead of data, created type synonym rather new type. using

type listofints = [int] 

means listofints same [int]. various reasons, can't use type synonyms in class instances default. makes sense--it easy make mistake trying write instance [int] 1 listofints, break.

using data wrap single type [int] or [double] same using newtype. however, newtype has advantage carries no runtime overhead @ all. best way write these types indeed newtype:

newtype listofints = listofints [int] newtype listofdoubles = listofdoubles [double] 

an important thing note when use data or newtype, have "unwrap" type if want @ content. can pattern matching:

instance incrementable listofints   increment (listofints ls) = listofints (map (\ x -> x + 1) ls) 

this unwraps listofints, maps function on contents , wraps up.

as long unwrap value way, instances should work.

on side note, can write map (\ x -> x + 1) map (+ 1), using called "operator section". means implicitly create lambda filling in whichever argument of operator missing. people find map (+ 1) version easier read because there less unnecessary noise.


Comments

Popular posts from this blog

php - Why I am getting the Error "Commands out of sync; you can't run this command now" -

linux - Does gcc have any options to add version info in ELF binary file? -

java - Are there any classes that implement javax.persistence.Parameter<T>? -