haskell - cannot construct the infinite type -


i want use applicative function , tried follow:

*readerexercise control.applicative> (+4) <*> (+3) 

then got following error message:

<interactive>:51:11: error:     * occurs check: cannot construct infinite type: ~ -> b       expected type: (a -> b) ->         actual type: ->     * in second argument of `(<*>)', namely `(+ 3)'       in expression: (+ 4) <*> (+ 3)       in equation `it': = (+ 4) <*> (+ 3)     * relevant bindings include         :: (a -> b) -> b (bound @ <interactive>:51:1) 

what expect return function 1 argument.
mean infinite type?

the error "occurs check: cannot construct [an] infinite type" results when haskell determines type variable (explicitly given programmer or implicitly introduced haskell) must satisfy condition implies need recursively defined in terms of in way lead infinitely "deep" type (i.e., type variable "occurs" in own definition).

it results either typo or conceptual error on part of programmer related confusing 2 different "levels of structure" in program.

as simple example, list of ints (type [int]) valid haskell type, , list of lists of ints ([[int]]) or list of lists of lists of lists of lists of ints ([[[[[int]]]]]) finite number of list levels allowed. can't have list of lists of lists of lists of lists, etc. way down -- infinite type. if haskell thinks want construct such type, it'll give "occurs check" error.

the following definition:

yuck (x:xs) = x == xs 

gives error reason. haskell knows left-hand side yuck takes list of unknown element type a variable x head of type a , variable xs tail of type [a]. rhs, operator (==) forces x , xs have same type -- in other words, implies constraint a ~ [a] tilde indicates "type equality". no finite type (no type finite number of list levels) has properties, invalid infinite type [[[[...forever...]]]] allow remove outer list level , still have same type left over, error.

the issue here programmer has confused 2 levels of structure: list xs , element x.

in specific example, reason error similar, harder explain. operator:

(<*>) :: (applicative f) => f (a -> b) -> f -> f b 

takes 2 applicative actions different underlying types: left-hand side has type given applicative functor f applied underlying type a -> b; right-hand side has type given same applicative functor f applied underlying type b.

you haven't told haskell applicative functor f meant use, haskell tries infer it. because lhs has type:

(+4) :: (num n) => n -> n 

haskell tries match type n -> n f (a -> b). may clearer write these types using prefix form of (->) type operator: haskell trying match (->) n n f ((->) b) f applicative functor.

fortunately, there's applicative functor instance (->) t type t. so, haskell reasons applicative functor want f = (->) n, , matches (->) n n = f n f ((->) b). implies n equal ((->) b). haskell tries match types on rhs, matching (->) n n = f n (->) n = f a. works, , implies n equal a.

now have problem. n simultaneously equal a -> b (from lhs) , a (from rhs). implies creation of infinite function type, looks like:

(((... forever ...)->b)->b)->b)->b 

which way remove outer ...->b , left same type. impossible infinite type, error.

the underlying problem you've made conceptual error. given working on readerexample, think intended use (->) n applicative functor instance, , haskell in agreement on point. in context:

(+4) :: (num n) -> n -> n 

is reader action reads number reader , adds 4 it. (+3) reader action reads number reader , adds 3 it.

however, (<*>) operator takes reader action on lhs reads reader produce function (not number!) applied result of using rhs read reader produce number. example, if defined:

multiplybyreader :: (num n) -> n -> n -> n multiplybyreader readernum input = readernum * input 

then:

multiplybyreader <*> (+4) 

or simpler version:

(*) <*> (+4) 

would make sense. intended meaning be: construct reader action (1) uses lhs read number reader create function multiplies reader; , (2) applies function number results applying rhs reader.

this equivalent \r -> r * (r + 4), can see:

> ((*) <*> (+4)) 5   -- same 5 * (5 + 4) 45 > 

when write (+3) <*> (+4), you're mixing 2 different structural levels: lhs reader yields number should instead yield function can applied number.

my best guess want create reader action applies (+4) reader number , applies (+3) result. in case, (+3) isn't reader action; it's function want apply result of reader action (+4), equivalent fmapping on reader action:

(+3) <$> (+4) 

of course, equivalently write directly as:

(+3) . (+4) 

both composite reader actions add 7 number read:

> ((+3) <$> (+4)) 5 12 > ((+3) . (+4)) 5 12 > 

Comments

Popular posts from this blog

angular - Ionic slides - dynamically add slides before and after -

minify - Minimizing css files -

Add a dynamic header in angular 2 http provider -