Lazy data structure evaluations

I read about lazy grades in haskell and ask a question. For example, we have the following calculations:

Prelude> let x = 1 + 1 :: Int Prelude> let y = (x,x) 

And after getting the x value:

 Prelude> :sprint x x = _ 

This is not appreciated. So now you can get the y value:

 Prelude> :sprint y y = (_,_) 

This is not appreciated either, because y depends on x and it unevaluated . Now try the same example, but without ::Int :

 Prelude> let x = 1 + 1 Prelude> let y = (x, x) Prelude> :sprint y y = _ 

Why is y value of _ instead of (_, _) when we try without ::Int ?

I see that they have different types:

 Prelude> let x = 1 + 1 Prelude> :tx x :: Num a => a Prelude> let x = 1 + 1 :: Int Prelude> :tx x :: Int 

But why do y values ​​depend on it?

Thanks.

+6
source share
1 answer

What happens when you point x to the type Num a => a , the compiler cannot know which instance of Num use when executing 1 + 1 . Instead, default is used. GHC defines default types for certain types of classes, so when there is no possible way to determine which specific type to use, it can still produce meaningful results without error. Therefore when you see

 > let x :: Num a => a | x = 1 + 1 > x 2 > :sprint x x = _ 

This is because GHCi selects Integer as the default type for Num , but when it does this, it does not save the result in memory x , since there is no way to find out, this is even the correct answer. That's why you see x = _ from :sprint , it actually did not evaluate x :: Num a => a , it rated x :: Integer . You can even touch yourself by default:

 > newtype MyInt = MyInt Int deriving (Eq) > > instance Show MyInt where | show (MyInt i) = show i > instance Num MyInt where | (MyInt x) + (MyInt y) = MyInt (x - y) | fromInteger = MyInt . fromInteger > > default (MyInt) > x 0 

So now we said that 1 + 1 = 0 ! Keep in mind that you'll probably never use this GHC functionality, but it's good to know.

+7
source

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


All Articles