What is the precise promise/guarantee the Haskell language provides with respect to referential transparency? At least the Haskell report does not mention this notion.
Consider the expression
(7^7^7`mod`5`mod`2)
And I want to know whether or not this expression is 1. For my safety, I will do perform this twice:
( (7^7^7`mod`5`mod`2)==1, [False,True]!!(7^7^7`mod`5`mod`2) )
which now gives (True,False)
with GHCi 7.4.1.
Evidently, this expression is now referentially opaque. How can I tell whether or not a program is subject to such behavior? I can inundate the program with ::
all over but that does not make it very readable. Is there any other class of Haskell programs in between that I miss? That is between a fully annotated and an unannotated one?
(Apart from the only somewhat related question I found on SO there must be something else on this)
What you think this has to do with referential transparency? Your uses of
7
,^
,mod
,5
,2
, and==
are applications of those variables to dictionaries, yes, but I don't see why you think that fact makes Haskell referentially opaque. Often applying the same function to different arguments produces different results, after all!Referential transparency has to do with this expression:
x
is here a single value, and should always have that same single value.By contrast, if you say:
(or use the expression inline, which is equivalent),
x
is now a function, and can return different values depending on theNum
argument you supply to it. You might as well complain thatlet f = (+1) in map f [1, 2, 3]
is[2, 3, 4]
, butlet f = (+3) in map f [1, 2, 3]
is[4, 5, 6]
and then say "Haskell gives different values formap f [1, 2, 3]
depending on the context so it's referentially opaque"!