Re: Confused about typing in ghci
On Wed, Apr 02, 2008 at 04:26:04PM -0400, Patrick Surry wrote: -- Why don't these (particularly g and g') all have the same type? Prelude :t (\x - x+1) (\x - x+1) :: (Num a) = a - a Prelude let g = (\x - x+1) Prelude :t g g :: Integer - Integer Prelude let g' x = x + 1 Prelude :t g' g' :: (Num a) = a - a It's the monomorphism restriction in action, along with defaulting. Basically, the rule is: Any binding of the form g = ... where there are no parameters *syntactically* must not be polymorphic with type-class restrictions. If you disable it with -fno-monomorphism-restriction then the differences go away. In addition, Haskell has some special-case defaulting rules for turning Num classed type-variables into concrete types, which explains the appearance of Integer specifically. The reason for existence of this restriction is that such a g may be recomputed for each use, much like a function call. This could lead to surprising behavior, though perfectly safe. In Haskell, it's not such a big deal, because of pure code, so some people prefer to turn the restriction off. Your options are to turn it off, always write syntactic parameters like g x = ..., or provide an explicit polymorphic type signature like g :: Num a = a - a. -- -- Matthew Danish -- user: mrd domain: cmu.edu -- OpenPGP public key: C24B6010 on keyring.debian.org ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: Confused about typing in ghci
On Wed, Apr 02, 2008 at 04:54:36PM -0400, Patrick Surry wrote: Thanks for the quick reply - I'm not sure I really understand exactly what your rule means, but it's led me over to http://www.haskell.org/haskellwiki/Monomorphism_restriction where it seems possible that I might eventually figure it out :) Really, don't overthink it too much. Anything that looks like g = ... syntactically (that means, as written in the file) cannot have a polymorphic type-class restricted type (something with a = in the type). The distinction being made is that g = ... has nothing but space in between the g and the =. No parameters syntactically. Any thoughts on the other question about where I can go to understand Haskell's precedence/associativity rules better (and avoid so many parens)? The Haskell Report, perhaps? -- -- Matthew Danish -- user: mrd domain: cmu.edu -- OpenPGP public key: C24B6010 on keyring.debian.org ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: hs-plugins -- simple example fails
On Fri, Feb 22, 2008 at 02:39:36PM +, Peter Collingbourne wrote: This could be caused by: * Loading two different object files which export the same symbol ^ I think this is the cause. Try factoring out Interface into its own module. -- -- Matthew Danish -- user: mrd domain: cmu.edu -- OpenPGP public key: C24B6010 on keyring.debian.org ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: Can't seem to figure how to compile
On Sun, Oct 21, 2007 at 01:46:16PM -0500, John Vogel wrote: gcc: installation problem, cannot exec `as': No such file or directory `as' is the assembler that gcc uses. Check your gcc. Can you even compile C programs successfully? -- -- Matthew Danish -- user: mrd domain: cmu.edu -- OpenPGP public key: C24B6010 on keyring.debian.org ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: is -fno-monomorphism-restriction evil?
On Tue, Oct 09, 2007 at 03:29:55PM -0300, Jorge Marques Pelizzoni wrote: It may be a side-effect of being a newbie, but many times I find the -fno-monomorphism-restriction quite handy. Is it intrinsically evil? I mean, has anyone had a bad time using it or does it imply some runtime performance overhead? I guess it is not portable, is it? The worst that can happen is unexpected repeated computation. This arises because type-class constraints on polymorphism act like a hidden parameter to a function. In bindings of the form: var = ... you may have expected that the value of var is only computed once. However, if the type of var is polymorphic with type-class constraints, then it is really a function. var dictionary = ... where the dictionary is a parameter which supplies the method definitions for whichever type is being used. Simple example, a function which reverses the parameters of the method compare of the Ord type-class: f = flip compare This turns into f ordDict = flip (compare ordDict) and now instead of being a simple variable binding it could be recomputed each time it is used. There are 3 ways to address this issue: 1) explicit parameters: the restriction only applies to bindings of the form var = ..., so if it's really a function, make those parameters explicit. f x y = compare y x 2) explicit type annotation: the restriction is lifted if you give an explicit type annotation. f :: Ord a = a - a - Ordering f = flip compare 3) -fno-monomorphism-restriction and equivalents Is -fno-monomorphism-restriction evil? No, I don't think so. I think there is some debate on whether the whole restriction should be lifted for Haskell' even. As for portability, you can now use: {-# LANGUAGE NoMonomorphismRestriction #-} at the top of your file. This should be more portable than a ghc-specific compiler option. See the GHC manual section on pragmas for the full details. -- -- Matthew Danish -- user: mrd domain: cmu.edu -- OpenPGP public key: C24B6010 on keyring.debian.org ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: 64-bit windows version?
On Sun, Jun 24, 2007 at 12:45:33PM +0100, Claus Reinke wrote: http://hackage.haskell.org/trac/ghc/wiki/Building/Windows#AWindowsbuildlogusingCygwin that would help others in the future, and they can send updates to the log when the details change. if you don't remember all the details, just write up what you remember, and let others fill in when they are actually doing an install. Instead of grabbing Cygwin, grab two other files along with MinGW installer. Presume you are at the SourceForge download page for MinGW (yes, I know SF is annoying): Under Current, unfold the full listing of packages: Unfold MinGW, MSYS, and MSYS Developer Tool Kit. Download the latest of + MinGW-*.exe, + MSYS-*.exe, + msysDTK-*.exe There aren't many .exe files, so it should be easy to pick them out. Install MinGW, then MSYS, then msysDTK. They are all ordinary Windows installers (NSIS I think). This installs your system in the approved manner, so it should be easy to later grab individual updates and simply unpack them into here. That should take care of your non-Haskell related packages. -- -- Matthew Danish -- user: mrd domain: cmu.edu -- OpenPGP public key: C24B6010 on keyring.debian.org ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: 64-bit windows version?
On Thu, Jun 21, 2007 at 12:35:15AM +1000, skaller wrote: Don't forget .. Mingw has to be installed too .. and in fact that is much harder. I tried to install MSYS and gave up. You're kidding right? There's Windows installer .exes for MinGW and MSYS. You download it, run it, and click Next a few times. -- -- Matthew Danish -- user: mrd domain: cmu.edu -- OpenPGP public key: C24B6010 on keyring.debian.org ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Seemingly subtle change causes large performance variation
Hello, I've been playing with the INTEST problem on SPOJ which demonstrates the ability to write a program which processes large quantities of input data. http://www.spoj.pl/problems/INTEST/ I came across some curious behavior while cleaning up the program. The original program, which runs fast (enough), is: module Main(main) where import Control.Monad import Data.Maybe import qualified Data.ByteString.Char8 as B divisibleBy :: Int - Int - Bool a `divisibleBy` n = a `rem` n == 0 main :: IO () main = do [n,k] - (map int . B.split ' ') `fmap` B.getLine :: IO [Int] let doLine :: Int - Int - IO Int doLine r _ = B.getLine = testDiv r testDiv r l | int l `divisibleBy` k = return (r + 1) | otherwise = return r foldM doLine 0 [1..n] = print where int :: B.ByteString - Int int = fst . fromJust . B.readInt But when I make a slight modification, the program chews up a ton more memory and takes more time: module Main(main) where import Control.Monad import Data.Maybe import qualified Data.ByteString.Char8 as B divisibleBy :: Int - Int - Bool a `divisibleBy` n = a `rem` n == 0 main :: IO () main = do [n,k] - (map int . B.split ' ') `fmap` B.getLine :: IO [Int] let doLine :: Int - Int - IO Int doLine r _ = B.getLine = return . testDiv r -- 'return' moved here ^^ testDiv r l | int l `divisibleBy` k = r + 1 | otherwise = r foldM doLine 0 [1..n] = print where int :: B.ByteString - Int int = fst . fromJust . B.readInt This program will generate sample data: import System.Random import System.Environment import Control.Monad main = do [n] - map read `fmap` getArgs :: IO [Int] k - randomRIO (1, 100) putStrLn $ unwords [show n, show k] replicateM_ n $ randomRIO (1, 10^9) = print Note that the same behavior occurs even if I manually inline the local function and try: return (if .. then .. else). Some sample runs: $ ghc/compiler/ghc-inplace ghc-6.7.20070601: no input files $ ghc/compiler/ghc-inplace --make -O2 intest.hs [1 of 1] Compiling Main ( intest.hs, intest.o ) Linking intest ... $ ghc/compiler/ghc-inplace --make -O2 intest_slow.hs [1 of 1] Compiling Main ( intest_slow.hs, intest_slow.o ) Linking intest_slow ... $ time ./intest +RTS -tstderr -RTS test1 ./intest +RTS -tstderr 8830 ghc: 134876896 bytes, 248 GCs, 28672/28672 avg/max bytes residency (1 samples), 2M in use, 0.00 INIT (0.00 elapsed), 0.12 MUT (0.12 elapsed), 0.00 GC (0.00 elapsed) :ghc real0m0.129s user0m0.124s sys 0m0.006s $ time ./intest_slow +RTS -tstderr -RTS test1 ./intest_slow +RTS -tstderr 8830 ghc: 144278584 bytes, 269 GCs, 7030784/21843968 avg/max bytes residency (6 samples), 38M in use, 0.00 INIT (0.00 elapsed), 0.13 MUT (0.14 elapsed), 0.10 GC (0.15 elapsed) :ghc real0m0.296s user0m0.238s sys 0m0.058s -- -- Matthew Danish -- user: mrd domain: cmu.edu -- OpenPGP public key: C24B6010 on keyring.debian.org ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: GHC as a library - getting output from GHCI
On Thu, May 10, 2007 at 09:34:53AM +0100, Simon Marlow wrote: And we do have support for this in GHC. $ ghci ___ ___ _ / _ \ /\ /\/ __(_) / /_\// /_/ / / | |GHC Interactive, version 6.7, for Haskell 98. / /_\\/ __ / /___| |http://www.haskell.org/ghc/ \/\/ /_/\/|_|Type :? for help. Loading package base ... linking ... done. Prelude :m + System.IO Prelude System.IO h - openFile out WriteMode {handle: out} Prelude System.IO GHC.Handle.hDuplicateTo h stdout -- as this point, GHCi goes quiet: I type :quit $ cat out Prelude System.IO :quit Leaving GHCi. Cheers, Simon Is there any way to create a handle which dumps its input into a string or memory buffer of some kind? I only know of the ability to open file/socket handles, and a quick browse of GHC/Handle.hs doesn't seem to indicate anything else. I'm not counting createPipe/fdToHandle because that is not portable. -- -- Matthew Danish -- user: mrd domain: cmu.edu -- OpenPGP public key: C24B6010 on keyring.debian.org ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: GHC as a library - getting output from GHCI
On Fri, May 04, 2007 at 08:12:55PM +0200, Pepe Iborra wrote: Mads On 04/05/2007, at 19:19, Mads Lindstr?m wrote: Hi Pepe I would have liked something cross-platform. Take a look at the unix-compat[1] package by Bjorn Bringert, although it looks like it won't help you. Maybe it can be extended. I'm attempting to do the same thing. But I don't see how wrapStmt can be implemented with System.Posix.Process. Documentation doesn't seem to indicate any function that deals with Handles, or returns Strings. I am unfamiliar with that module however. -- -- Matthew Danish -- user: mrd domain: cmu.edu -- OpenPGP public key: C24B6010 on keyring.debian.org ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: GHC as a library - getting output from GHCI
On Wed, May 09, 2007 at 10:48:15PM +0200, Mads Lindstr?m wrote: Hi Look at System.Posix.IO I do not know if that module can do what you want. But it does deal with FileDescriptors and handles. Maybe the dup function can help you. According to http://www2.lib.uchicago.edu/~keith//tcl-course/topics/processes.html it does: The dup implements the dup system call, which duplicates one desired open file descriptor into another. This can be used connect standard input or standard output to a pipe. This sample code shows how a parent process can fork the standard Unix sort command and then feed it data to be sorted. A simple extension would allow the child to write the results back to the parent. But I have not tested it yet, and I am not really familiar with Unix inter-process communication. Right, good thinking. This is what I've come up with for Unix-only: module WrapIO where import System.IO import System.Posix.IO import Control.Exception wrapIO :: IO a - IO (a, String) wrapIO action = do oldStdOutput - dup stdOutput (rd, wr) - createPipe dupTo wr stdOutput v - action h - fdToHandle rd closeFd wr s - hGetContents h return (v, s) `finally` do dupTo oldStdOutput stdOutput closeFd oldStdOutput Unfortunately, dupTo will not work on Win32 afaik. -- -- Matthew Danish -- user: mrd domain: cmu.edu -- OpenPGP public key: C24B6010 on keyring.debian.org ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: scripts on unix
On Wed, Mar 14, 2007 at 07:31:55PM +, Frederik Eaton wrote: Hello, What is the proper technique for creating a Haskell script on a Unix system? File.lhs: #!/usr/bin/env runhaskell \begin{code} ... \end{code} With a literate code file, the #! should cause no issues. -- -- Matthew Danish -- user: mrd domain: cmu.edu -- OpenPGP public key: C24B6010 on keyring.debian.org ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users