why cannot i get the value of a IORef variable ?

let aaa = unsafePerformIO $ newIORef [] writeIORef aaa [1,2,3] readIORef aaa [(),(),()]
sincerely! -- View this message in context: http://www.nabble.com/why-cannot-i-get-the-value-of-a-IORef-variable---tp260... Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

I assume you're trying this at the GHCi prompt, which is where you're problem is coming from, specifically on the first line. When you do:
let aaa = unsafePerformIO $ newIORef [] GHCi takes a wild stab at the type of [] and comes up with the type [()], so now you have a IORef [()] type, which is why when you try to store [1,2,3] in the IORef you get back [(),(),()]. Try this instead and it should work: let aaa = unsafePerformIO $ newIORef ([] :: [Int])
-R. Kyle Murphy
--
Curiosity was framed, Ignorance killed the cat.
On Thu, Oct 22, 2009 at 01:02, zaxis
let aaa = unsafePerformIO $ newIORef [] writeIORef aaa [1,2,3] readIORef aaa [(),(),()]
sincerely! -- View this message in context: http://www.nabble.com/why-cannot-i-get-the-value-of-a-IORef-variable---tp260... Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Yes, it works now! thank you very much! Kyle Murphy-2 wrote:
I assume you're trying this at the GHCi prompt, which is where you're problem is coming from, specifically on the first line. When you do:
let aaa = unsafePerformIO $ newIORef [] GHCi takes a wild stab at the type of [] and comes up with the type [()], so now you have a IORef [()] type, which is why when you try to store [1,2,3] in the IORef you get back [(),(),()]. Try this instead and it should work: let aaa = unsafePerformIO $ newIORef ([] :: [Int])
-R. Kyle Murphy -- Curiosity was framed, Ignorance killed the cat.
On Thu, Oct 22, 2009 at 01:02, zaxis
wrote: let aaa = unsafePerformIO $ newIORef [] writeIORef aaa [1,2,3] readIORef aaa [(),(),()]
sincerely! -- View this message in context: http://www.nabble.com/why-cannot-i-get-the-value-of-a-IORef-variable---tp260... Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- View this message in context: http://www.nabble.com/why-cannot-i-get-the-value-of-a-IORef-variable---tp260... Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

zaxis
let aaa = unsafePerformIO $ newIORef [] writeIORef aaa [1,2,3] readIORef aaa [(),(),()]
What in Haskells name do you think you're doing? Don't use unsafePerformIO like that! Its unnecessary and a bit concerning, really. Prelude> :m Data.IORef Prelude Data.IORef> x <- newIORef [] :: IO (IORef [Int]) Prelude Data.IORef> writeIORef x [1,2,3] Prelude Data.IORef> readIORef x [1,2,3]
sincerely! -- View this message in context: http://www.nabble.com/why-cannot-i-get-the-value-of-a-IORef-variable---tp260... Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

thank you! In fact i really donot understand "unsafePerformIO" very much ! Thomas DuBuisson wrote:
zaxis
wrote: let aaa = unsafePerformIO $ newIORef [] writeIORef aaa [1,2,3] readIORef aaa [(),(),()]
What in Haskells name do you think you're doing? Don't use unsafePerformIO like that! Its unnecessary and a bit concerning, really.
Prelude> :m Data.IORef Prelude Data.IORef> x <- newIORef [] :: IO (IORef [Int]) Prelude Data.IORef> writeIORef x [1,2,3] Prelude Data.IORef> readIORef x [1,2,3]
sincerely! -- View this message in context: http://www.nabble.com/why-cannot-i-get-the-value-of-a-IORef-variable---tp260... Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- View this message in context: http://www.nabble.com/why-cannot-i-get-the-value-of-a-IORef-variable---tp260... Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

zaxis> thank you! In fact i really donot understand zaxis> "unsafePerformIO" very much ! Then all you have to understand is - never use it! -- Colin Adams Preston Lancashire

For clarity, one trick that uses "unsafePerformIO" which you may have seen posted on this list earlier today is the following way of creating a globally visible IORef: import Data.IORef import System.IO.Unsafe *** counter = unsafePerformIO $ newIORef 0 *** next = do modifyIORef counter (+1) readIORef counter The key line has been starred; this created a counter IORef that "next" could access without having to be explicitly given it on each call. Personally, though, I never use this approach because it creates a race condition. Because Haskell is lazy, "counter" will not be evaluated until the first time that it is accessed. If two threads access it at the same time before it has been evaluated, then in GHC there are conditions under which they could both evaluate it and create a new IORef simultaneously, resulting in each thread effectively ending up with its own counter variable when you specifically wanted a globally shared counter variable. This is why I personally use the ReaderT monad if I want to implicitly share a global IORef, rather than using this trick. Cheers, Greg On Oct 21, 2009, at 10:50 PM, Colin Paul Adams wrote:
zaxis> thank you! In fact i really donot understand zaxis> "unsafePerformIO" very much !
Then all you have to understand is - never use it! -- Colin Adams Preston Lancashire _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

For clarity, one trick that uses "unsafePerformIO" which you may have seen posted on this list earlier today is the following way of creating a globally visible IORef:
import Data.IORef import System.IO.Unsafe
*** counter = unsafePerformIO $ newIORef 0 ***
next = do modifyIORef counter (+1) readIORef counter
This is still unsafe but it can evidently be slightly improved with NOINLINE pragma: {-# NOINLINE counter #-} counter = unsafePerformIO $ newIORef 0 without said pragma the counter could be initialized numerous times, as I understand it. All this said, I hope people avoid unsafePerformIO for mutable globals - reader monad, state monad, and partial application should be sufficient tools. Thomas

On Thu, Oct 22, 2009 at 2:23 AM, Gregory Crosswhite
For clarity, one trick that uses "unsafePerformIO" which you may have seen posted on this list earlier today is the following way of creating a globally visible IORef:
import Data.IORef import System.IO.Unsafe
*** counter = unsafePerformIO $ newIORef 0 ***
Danger! If the monomorphism restriction is disabled, this ends up
creating a value of type forall a. Num a => IORef a, which can be used
to break type safety.
More generally,
cell :: IORef a
cell = unsafePerformIO $ newIORef undefined
unsafeCoerce :: a -> b
unsafeCoerce x = unsafePerformIO $ do
writeIORef cell x
readIORef cell
This way lies segmentation faults. That "unsafe" is there for a reason.
--
Dave Menendez

Yes, I was once taught that "Every time you use unsafePerformIO, God kills a kitten," so every time I consider using it I first ask myself: is this really worth an innocent kitten's life? Cheers, Greg On Oct 22, 2009, at 11:32 AM, David Menendez wrote:
On Thu, Oct 22, 2009 at 2:23 AM, Gregory Crosswhite
wrote: For clarity, one trick that uses "unsafePerformIO" which you may have seen posted on this list earlier today is the following way of creating a globally visible IORef:
import Data.IORef import System.IO.Unsafe
*** counter = unsafePerformIO $ newIORef 0 ***
Danger! If the monomorphism restriction is disabled, this ends up creating a value of type forall a. Num a => IORef a, which can be used to break type safety.
More generally,
cell :: IORef a cell = unsafePerformIO $ newIORef undefined
unsafeCoerce :: a -> b unsafeCoerce x = unsafePerformIO $ do writeIORef cell x readIORef cell
This way lies segmentation faults. That "unsafe" is there for a reason.
-- Dave Menendez
http://www.eyrie.org/~zednenem/

Well, I apologize for starting this whole thread which involves so many dead kittens :( I was just trying to help answer a question :) I guess I assumed too much.. that someone would think to be careful when using a function with the word 'unsafe' in it... So, be warned, all Haskellers! Be careful when using any function that starts with the word 'unsafe'! You may kill a kitten! And I guess this says something about using 'unsafe' functions... http://upload.wikimedia.org/wikipedia/en/1/11/God-kills-kitten.jpg (NSFW)... Cheers and sorry all, Tim On Thu, Oct 22, 2009 at 1:59 PM, Gregory Crosswhite < gcross@phys.washington.edu> wrote:
Yes, I was once taught that "Every time you use unsafePerformIO, God kills a kitten," so every time I consider using it I first ask myself: is this really worth an innocent kitten's life?
Cheers, Greg
On Oct 22, 2009, at 11:32 AM, David Menendez wrote:
On Thu, Oct 22, 2009 at 2:23 AM, Gregory Crosswhite
wrote: For clarity, one trick that uses "unsafePerformIO" which you may have seen posted on this list earlier today is the following way of creating a globally visible IORef:
import Data.IORef import System.IO.Unsafe
*** counter = unsafePerformIO $ newIORef 0 ***
Danger! If the monomorphism restriction is disabled, this ends up creating a value of type forall a. Num a => IORef a, which can be used to break type safety.
More generally,
cell :: IORef a cell = unsafePerformIO $ newIORef undefined
unsafeCoerce :: a -> b unsafeCoerce x = unsafePerformIO $ do writeIORef cell x readIORef cell
This way lies segmentation faults. That "unsafe" is there for a reason.
-- Dave Menendez
<http://www.eyrie.org/~zednenem/ http://www.eyrie.org/%7Ezednenem/> _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

"Gregory" == Gregory Crosswhite
writes:
Gregory> Yes, I was once taught that "Every time you use Gregory> unsafePerformIO, God kills a kitten," so every time I Gregory> consider using it I first ask myself: is this really Gregory> worth an innocent kitten's life? I've changed my mind. Everyone go out and use unsafePerformIO all the time. That way we can get rid of all those mudering kittens, and the dragonflies will live longer. -- Colin Adams Preston Lancashire

Colin Paul Adams wrote:
"Gregory" == Gregory Crosswhite
writes: Gregory> Yes, I was once taught that "Every time you use Gregory> unsafePerformIO, God kills a kitten," so every time I Gregory> consider using it I first ask myself: is this really Gregory> worth an innocent kitten's life?
I've changed my mind.
Everyone go out and use unsafePerformIO all the time. That way we can get rid of all those mudering kittens, and the dragonflies will live longer.
You're missing the bigger picture. It's clear from the literature[*] that the IO monad, the type system, and possibly even Haskell itself, is powered by kittens. If you use up all the kittens, Haskell will just stop working. Terms won't even reach WHNF, they'll be stuck in KAF, Kittenless Abnormal Form. On the plus side, this does make for a slogan with high market appeal: Haskell: Kittens inside -- [*] http://arcanux.org/lambdacats.html

On Thu, Oct 22, 2009 at 1:32 PM, David Menendez
On Thu, Oct 22, 2009 at 2:23 AM, Gregory Crosswhite
wrote: For clarity, one trick that uses "unsafePerformIO" which you may have seen posted on this list earlier today is the following way of creating a globally visible IORef:
import Data.IORef import System.IO.Unsafe
*** counter = unsafePerformIO $ newIORef 0 ***
Danger! If the monomorphism restriction is disabled, this ends up creating a value of type forall a. Num a => IORef a, which can be used to break type safety.
More generally,
cell :: IORef a cell = unsafePerformIO $ newIORef undefined
unsafeCoerce :: a -> b unsafeCoerce x = unsafePerformIO $ do writeIORef cell x readIORef cell
This way lies segmentation faults. That "unsafe" is there for a reason.
This is exactly what happened in the original example.
participants (10)
-
Anton van Straaten
-
Colin Paul Adams
-
David Menendez
-
Derek Elkins
-
Gregory Crosswhite
-
Kyle Murphy
-
Martijn van Steenbergen
-
Thomas DuBuisson
-
Tim Wawrzynczak
-
zaxis