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 thatx
with the typeNum a => a
is 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 thatx
with the typeNum a => a
is 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 thatx
with the typeNum a => a
is 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 thatx
with the typeNum a => a
is reevaluated when given different instances ofNum
.– pdexter
Nov 28 '18 at 10:34