Confused by converting WHNF to NF in Haskell [duplicate]
This question already has an answer here:
:sprint for polymorphic values?
1 answer
In a simple example, converting WHNF to NF by printing works fine
Prelude> let x = 1 + 2 :: Int
Prelude> :sprint x
x = _
Prelude> x
3
Prelude> :sprint x
x = 3
But in a case, the type is not declared it doesn't work.
Prelude> let x = 1 + 2
Prelude> :sprint x
x = _
Prelude> x
3
Prelude> :sprint x
x = _
Can you explain in some details why conversion doesn't work in the last case?
haskell weak-head-normal-form
marked as duplicate by Daniel Wagner
StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;
$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');
$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Nov 28 '18 at 17:52
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
add a comment |
This question already has an answer here:
:sprint for polymorphic values?
1 answer
In a simple example, converting WHNF to NF by printing works fine
Prelude> let x = 1 + 2 :: Int
Prelude> :sprint x
x = _
Prelude> x
3
Prelude> :sprint x
x = 3
But in a case, the type is not declared it doesn't work.
Prelude> let x = 1 + 2
Prelude> :sprint x
x = _
Prelude> x
3
Prelude> :sprint x
x = _
Can you explain in some details why conversion doesn't work in the last case?
haskell weak-head-normal-form
marked as duplicate by Daniel Wagner
StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;
$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');
$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Nov 28 '18 at 17:52
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
3
Without an explicit type::t x -- x :: Num a => a. Which can be inserted into different expressions with a different type.x :: Int -- 3,x :: Float -- 3.0. Using these hints we can assume thatxwith the typeNum a => ais reevaluated when given different instances ofNum.
– pdexter
Nov 28 '18 at 10:34
add a comment |
This question already has an answer here:
:sprint for polymorphic values?
1 answer
In a simple example, converting WHNF to NF by printing works fine
Prelude> let x = 1 + 2 :: Int
Prelude> :sprint x
x = _
Prelude> x
3
Prelude> :sprint x
x = 3
But in a case, the type is not declared it doesn't work.
Prelude> let x = 1 + 2
Prelude> :sprint x
x = _
Prelude> x
3
Prelude> :sprint x
x = _
Can you explain in some details why conversion doesn't work in the last case?
haskell weak-head-normal-form
This question already has an answer here:
:sprint for polymorphic values?
1 answer
In a simple example, converting WHNF to NF by printing works fine
Prelude> let x = 1 + 2 :: Int
Prelude> :sprint x
x = _
Prelude> x
3
Prelude> :sprint x
x = 3
But in a case, the type is not declared it doesn't work.
Prelude> let x = 1 + 2
Prelude> :sprint x
x = _
Prelude> x
3
Prelude> :sprint x
x = _
Can you explain in some details why conversion doesn't work in the last case?
This question already has an answer here:
:sprint for polymorphic values?
1 answer
haskell weak-head-normal-form
haskell weak-head-normal-form
asked Nov 28 '18 at 10:24
Bogdan RuzhitskiyBogdan Ruzhitskiy
5531515
5531515
marked as duplicate by Daniel Wagner
StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;
$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');
$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Nov 28 '18 at 17:52
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
marked as duplicate by Daniel Wagner
StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;
$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');
$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Nov 28 '18 at 17:52
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
3
Without an explicit type::t x -- x :: Num a => a. Which can be inserted into different expressions with a different type.x :: Int -- 3,x :: Float -- 3.0. Using these hints we can assume thatxwith the typeNum a => ais reevaluated when given different instances ofNum.
– pdexter
Nov 28 '18 at 10:34
add a comment |
3
Without an explicit type::t x -- x :: Num a => a. Which can be inserted into different expressions with a different type.x :: Int -- 3,x :: Float -- 3.0. Using these hints we can assume thatxwith the typeNum a => ais reevaluated when given different instances ofNum.
– pdexter
Nov 28 '18 at 10:34
3
3
Without an explicit type:
:t x -- x :: Num a => a. Which can be inserted into different expressions with a different type. x :: Int -- 3 , x :: Float -- 3.0. Using these hints we can assume that x with the type Num a => a is reevaluated when given different instances of Num.– pdexter
Nov 28 '18 at 10:34
Without an explicit type:
:t x -- x :: Num a => a. Which can be inserted into different expressions with a different type. x :: Int -- 3 , x :: Float -- 3.0. Using these hints we can assume that x with the type Num a => a is reevaluated when given different instances of Num.– pdexter
Nov 28 '18 at 10:34
add a comment |
1 Answer
1
active
oldest
votes
Since in GHCi the monomoprhism restriction is disabled, the last x is a polymorphic value of type x :: Num a => a. So it is not a simple integer, but a kind-of function DictNum a -> a which is ready to create a value in any numeric type.
Indeed, x :: Int, x :: Float, x :: Double will run and produce different values. These values are numerically the same, but computationally different, since they are representations in different types.
Since x is, essentially, "multiple values, generated on demand", there is no single WHNF or NF here.
Note that if we compute (x :: Int) + (x :: Int), then x is being recomputed twice: GHC in general will not "cache" the WHNF at type Int for successive computations. This is similar to f 3 + f 3, where f 3 is not cached (memoized).
This duplicate computation is precisely what the monomorphism restriction tries to avoid.
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Since in GHCi the monomoprhism restriction is disabled, the last x is a polymorphic value of type x :: Num a => a. So it is not a simple integer, but a kind-of function DictNum a -> a which is ready to create a value in any numeric type.
Indeed, x :: Int, x :: Float, x :: Double will run and produce different values. These values are numerically the same, but computationally different, since they are representations in different types.
Since x is, essentially, "multiple values, generated on demand", there is no single WHNF or NF here.
Note that if we compute (x :: Int) + (x :: Int), then x is being recomputed twice: GHC in general will not "cache" the WHNF at type Int for successive computations. This is similar to f 3 + f 3, where f 3 is not cached (memoized).
This duplicate computation is precisely what the monomorphism restriction tries to avoid.
add a comment |
Since in GHCi the monomoprhism restriction is disabled, the last x is a polymorphic value of type x :: Num a => a. So it is not a simple integer, but a kind-of function DictNum a -> a which is ready to create a value in any numeric type.
Indeed, x :: Int, x :: Float, x :: Double will run and produce different values. These values are numerically the same, but computationally different, since they are representations in different types.
Since x is, essentially, "multiple values, generated on demand", there is no single WHNF or NF here.
Note that if we compute (x :: Int) + (x :: Int), then x is being recomputed twice: GHC in general will not "cache" the WHNF at type Int for successive computations. This is similar to f 3 + f 3, where f 3 is not cached (memoized).
This duplicate computation is precisely what the monomorphism restriction tries to avoid.
add a comment |
Since in GHCi the monomoprhism restriction is disabled, the last x is a polymorphic value of type x :: Num a => a. So it is not a simple integer, but a kind-of function DictNum a -> a which is ready to create a value in any numeric type.
Indeed, x :: Int, x :: Float, x :: Double will run and produce different values. These values are numerically the same, but computationally different, since they are representations in different types.
Since x is, essentially, "multiple values, generated on demand", there is no single WHNF or NF here.
Note that if we compute (x :: Int) + (x :: Int), then x is being recomputed twice: GHC in general will not "cache" the WHNF at type Int for successive computations. This is similar to f 3 + f 3, where f 3 is not cached (memoized).
This duplicate computation is precisely what the monomorphism restriction tries to avoid.
Since in GHCi the monomoprhism restriction is disabled, the last x is a polymorphic value of type x :: Num a => a. So it is not a simple integer, but a kind-of function DictNum a -> a which is ready to create a value in any numeric type.
Indeed, x :: Int, x :: Float, x :: Double will run and produce different values. These values are numerically the same, but computationally different, since they are representations in different types.
Since x is, essentially, "multiple values, generated on demand", there is no single WHNF or NF here.
Note that if we compute (x :: Int) + (x :: Int), then x is being recomputed twice: GHC in general will not "cache" the WHNF at type Int for successive computations. This is similar to f 3 + f 3, where f 3 is not cached (memoized).
This duplicate computation is precisely what the monomorphism restriction tries to avoid.
edited Nov 28 '18 at 10:39
answered Nov 28 '18 at 10:34
chichi
76.6k285144
76.6k285144
add a comment |
add a comment |
3
Without an explicit type:
:t x -- x :: Num a => a. Which can be inserted into different expressions with a different type.x :: Int -- 3,x :: Float -- 3.0. Using these hints we can assume thatxwith the typeNum a => ais reevaluated when given different instances ofNum.– pdexter
Nov 28 '18 at 10:34