No instance for (Data.Functor.Classes.Show1 ExprF) - haskell

I've written a small program to find the prime factorization of a number. Everything seems to compile except for the main function, which complains about not being able to find a Show1 instance.
{-# LANGUAGE DeriveFunctor #-}
module FactorAnamorphism where
import Data.Functor.Foldable
import Data.List
nextPrimeFactor :: Integer -> Maybe Integer
nextPrimeFactor n = find (\x -> n `mod` x /= 0) [2..(floor $ sqrt $ fromIntegral n)]
data ExprF r = FactorF Integer | MultF r r deriving (Show, Functor)
type Expr = Fix ExprF
factor :: Integer -> Expr
factor = ana coAlg where
coAlg fac = case (nextPrimeFactor fac) of
Just prime -> MultF prime (fac `div` prime)
Nothing -> FactorF fac
main :: IO ()
main = putStrLn $ show $ factor 10
Logs:
% stack build
haskell-playground-0.1.0.0: build (lib + exe)
Preprocessing library haskell-playground-0.1.0.0...
Preprocessing executable 'factor-anamorphism' for
haskell-playground-0.1.0.0...
[1 of 1] Compiling FactorAnamorphism ( app/FactorAnamorphism.hs, .stack-work/dist/x86_64-osx/Cabal-1.24.2.0/build/factor-anamorphism/factor-anamorphism-tmp/FactorAnamorphism.o )
/Users/ian/proj/macalinao/haskell-playground/app/FactorAnamorphism.hs:22:19: error:
• No instance for (Data.Functor.Classes.Show1 ExprF)
arising from a use of ‘show’
• In the second argument of ‘($)’, namely ‘show $ factor 10’
In the expression: putStrLn $ show $ factor 10
In an equation for ‘main’: main = putStrLn $ show $ factor 10
-- While building package haskell-playground-0.1.0.0 using:
/Users/ian/.stack/setup-exe-cache/x86_64-osx/Cabal-simple_mPHDZzAJ_1.24.2.0_ghc-8.0.2 --builddir=.stack-work/dist/x86_64-osx/Cabal-1.24.2.0 build lib:haskell-playground exe:factor-anamorphism exe:haskell-playground-exe --ghc-options " -ddump-hi -ddump-to-file"
Process exited with code: ExitFailure 1

The instance of Show for Fix is: Show1 f => Show (Fix f), which is why the compiler expects Show1 ExprF.
Show1 can be found in base under Data.Functor.Classes, and there is a TH script to derive it in Text.Show.Deriving from deriving-compat.

Related

How can I randomly generate a string 5 symbols long in haskell?

I'm a newbie so I'm having problems doing this:P
Currently I have tried this:
xs1 :: RandomGen g => Int -> g -> [[Char]]
xs1 n = sequence $ replicate n $ randomRs ('!', '~' ::Char)
but I can't give this string to my function:
fun1 :: (Eq a, Num a) => [a] -> [Char] -> [Char]
fun1 a xs1=[if (a!!n==1) then (xs1!!n) else b | n <- [0, 1,2,3,4]]
any help would be greatly appreciated
IMO the easiest way for a beginner to use random stuff is randomIO or randomRIO - here is an example printing 5 random characters (in the range '!' to '~'):
import Control.Monad (replicateM)
import System.Random (Random(randomRIO))
randomString :: Int -> IO String
randomString len = replicateM len $ randomRIO ('!', '~')
select :: (Num f, Eq f) => [f] -> String -> String
select =
zipWith (\f c -> if f == 1 then c else ' ')
main :: IO ()
main = do
-- there will be a warning without the `:: Int`
s <- select [1 :: Int,0,1,0,1] <$> randomString 5
putStrLn s
I'm using randomRIO here because using just randomIO will give you random characters from all over the place most likely all unprintable ;)
I don't know what you are trying to do with fun1 but I'll gone edit if you make it clear
How can I randomly generate a string 5 symbols long ?
Due to the use of randomRs, your xs1 function returns a list of infinitely long strings.
Also, as xs1 is a function not a list, you cannot really index it thru the !! operator.
Please please: paste the full text of the error message in your question, rather than just writing:
“I can't give this string to my function:”.
In order to generate random strings, you need two things:
a generator, typically returned by mkStdGen or mkTFGen
a monadic action object with the appropriate return type
Let's try to do that under the ghci Haskell interpreter:
$ ghci
GHCi, version 8.8.4: https://www.haskell.org/ghc/ :? for help
λ>
λ> import System.Random
λ> import Control.Monad.Random
λ>
So let's get a generator first:
λ>
λ> seed = 42
λ> gen1 = mkStdGen seed
λ>
Then let's write the action object:
λ>
λ> act5 = sequence $ replicate 5 (getRandomR ('!', '~' ::Char))
λ>
λ> :type act5
act5 :: MonadRandom m => m [Char]
λ>
The action object is essentially a wrapper around a transition function that takes a generator and returns some (output value, new generator) pair.
Finally, we combine these two things thru the runRand :: Rand g a -> g -> (a, g) library function, which returns both the value you want and an updated generator:
λ>
λ> (str1, gen2) = runRand act5 gen1
λ>
λ> str1
"D6bK/"
λ>
And we can even get a second pseudo-random string, courtesy of the updated generator:
λ>
λ> (str2, gen3) = runRand act5 gen2
λ>
λ> str2
"|}#5h"
λ>
And so on ... As you can see, it is not really necessary to use the IO monad for this.
A slight generalization:
Now, say you need 6 such random strings:
λ>
λ> act5rep = sequence (replicate 6 act5)
λ>
λ> :type act5rep
act5rep :: MonadRandom m => m [[Char]]
λ>
λ> (strs, newGen) = runRand act5rep gen1
λ>
λ> strs
["D6bK/","|}#5h","0|qSQ","h4:.1","3+e-}","}eu,I"]
λ>

'no instance' error when importing custom module in ghci

I am trying to import a custom module into main using ghci and I am getting this error I don't really understand.
Main.hs
module Main where
import Newton (my_sqrt)
main = my_sqrt 25
Newton.hs
module Newton where
deriv f x = (f(x + dx) - f(x))/dx
where dx = 0.0001
newton f = until satis improve
where satis y = abs(f y) < eps
eps = 0.0001
improve y = y - (f y/deriv f y)
my_sqrt x = newton f x
where f y = y^2 - x
my_cubrt x = newton f x
where f y = y**3 - x
I try to load these into ghci using
:l Main.hs
I get this error
Main.hs:9:8: error:
• No instance for (Fractional (IO t0))
arising from a use of ‘my_sqrt’
• In the expression: my_sqrt 25
In an equation for ‘main’: main = my_sqrt 25
Main.hs:9:16: error:
• No instance for (Num (IO t0)) arising from the literal ‘25’
• In the first argument of ‘my_sqrt’, namely ‘25’
In the expression: my_sqrt 25
In an equation for ‘main’: main = my_sqrt 25
Failed, modules loaded: Newton.
How do I solve this issue?
The type of main is required to be IO ().
The type of sqrt 25 is, apparently, Fractional t => t (it is really advisable to always include type signatures for your top-level entities in the program; you miss those).
To reconcile the two you can define e.g.
main :: IO ()
main = print (sqrt 25)
because the type of print is print :: Show a => a -> IO ().

Arbitrary String generator in Haskell (Test.QuickCheck.Gen)

I am struggling on Real World Haskell Chapter 11 quickCheck generator implementation for a an algebraic data type.
Following the book implementation (which was published in 2008), I came up with the following:
-- file: ch11/Prettify2.hs
module Prettify2(
Doc(..)
) where
data Doc = Empty
| Char Char
| Text String
| Line
| Concat Doc Doc
| Union Doc Doc
deriving (Show, Eq)
And my Arbitrary implementation:
-- file: ch11/Arbitrary.hs
import System.Random
import Test.QuickCheck.Gen
import qualified Test.QuickCheck.Arbitrary
class Arbitrary a where
arbitrary :: Gen a
-- elements' :: [a] => Gen a {- Expected a constraint, but ‘[a]’ has kind ‘*’ -}
-- choose' :: Random a => (a, a) -> Gen a
-- oneof' :: [Gen a] -> a
data Ternary = Yes
| No
| Unknown
deriving(Eq, Show)
instance Arbitrary Ternary where
arbitrary = do
n <- choose (0, 2) :: Gen Int
return $ case n of
0 -> Yes
1 -> No
_ -> Unknown
instance (Arbitrary a, Arbitrary b) => Arbitrary (a, b) where
arbitrary = do
x <- arbitrary
y <- arbitrary
return (x, y)
instance Arbitrary Char where
arbitrary = elements (['A'..'Z'] ++ ['a' .. 'z'] ++ " ~!##$%^&*()")
I tried the two following implementation with no success:
import Prettify2
import Control.Monad( liftM, liftM2 )
instance Arbitrary Doc where
arbitrary = do
n <- choose (1,6) :: Gen Int
case n of
1 -> return Empty
2 -> do x <- arbitrary
return (Char x)
3 -> do x <- arbitrary
return (Text x)
4 -> return Line
5 -> do x <- arbitrary
y <- arbitrary
return (Concat x y)
6 -> do x <- arbitrary
y <- arbitrary
return (Union x y)
instance Arbitrary Doc where
arbitrary =
oneof [ return Empty
, liftM Char arbitrary
, liftM Text arbitrary
, return Line
, liftM2 Concat arbitrary arbitrary
, liftM2 Union arbitrary arbitrary ]
But it doesn't compile since No instance for (Arbitrary String)
I tried then to implement the instance for Arbitrary String in the following ways:
import qualified Test.QuickCheck.Arbitrary but it does not implement Arbitrary String neither
installing Test.RandomStrings hackage link
instance Arbitrary String where
arbitrary = do
n <- choose (8, 16) :: Gen Int
return $ randomWord randomASCII n :: Gen String
With the following backtrace:
$ ghci
GHCi, version 7.10.3: http://www.haskell.org/ghc/ :? for help
Prelude> :l Arbitrary.hs
[1 of 2] Compiling Prettify2 ( Prettify2.hs, interpreted )
[2 of 2] Compiling Main ( Arbitrary.hs, interpreted )
Arbitrary.hs:76:9:
The last statement in a 'do' block must be an expression
return <- randomWord randomASCII n :: Gen String
Failed, modules loaded: Prettify2
Would you have any good suggestion about how to implement this particular generator and - more in general - how to proceed in these cases?
Thank you in advance
Don't define a new Arbitrary type class, import Test.QuickCheck instead. It defines most of these instances for you. Also be careful about the version of quickcheck, RWH assumes version 1.
The resulting full implementation will be:
-- file: ch11/Arbitrary.hs
import Test.QuickCheck
import Prettify2
import Control.Monad( liftM, liftM2 )
data Ternary = Yes
| No
| Unknown
deriving(Eq, Show)
instance Arbitrary Ternary where
arbitrary = do
n <- choose (0, 2) :: Gen Int
return $ case n of
0 -> Yes
1 -> No
_ -> Unknown
instance Arbitrary Doc where
arbitrary =
oneof [ return Empty
, liftM Char arbitrary
, liftM Text arbitrary
, return Line
, liftM2 Concat arbitrary arbitrary
, liftM2 Union arbitrary arbitrary ]

Haskell quickcheck issue

I am writing a simple test using quickcheck.
import Test.QuickCheck
f :: Int -> Int
f x
| x < 0 = (-x)
| otherwise = x
main = do
putStrLn "Testing"
quickCheck ((\x -> ((f x) >= 0)) :: Int -> Bool)
Whenever I run this via $ runhaskell test.hs, I see one of 2 different results.
Either I get:
Testing
+++ OK, passed 100 tests.
Or:
I get no output, and the program terminates.
I cannot reason about this behavior.
This is on Quickcheck 2.5.1.1, and ghc 7.4.2.

Warning on specialisations when compiling Haskell Code with ghc

I get the following error when trying to compile
$ ghc --make -O2 -Wall -fforce-recomp
[1 of 1] Compiling Main (
isPrimeSmart.hs, isPrimeSmart.o )
SpecConstr
Function `$wa{v s2we} [lid]'
has two call patterns, but the limit is 1
Use -fspec-constr-count=n to set the bound
Use -dppr-debug to see specialisations Linking isPrimeSmart
...
My code is:
{-# OPTIONS_GHC -O2 -optc-O2 #-}
import qualified Data.ByteString.Lazy.Char8 as StrL -- StrL is STRing Library
import Data.List
-- read in a file. First line tells how many cases. Each case is on a separate
-- line with the lower an upper bounds separated by a space. Print all primes
-- between the lower and upper bound. Separate results for each case with
-- a blank line.
main :: IO ()
main = do
let factors = takeWhile (<= (ceiling $ sqrt (1000000000::Double))) allPrimes
(l:ls) <- StrL.lines `fmap` StrL.getContents
let numCases = readInt l
let cases = (take numCases ls)
sequence_ $ intersperse (putStrLn "") $ map (doLine factors) cases
-- get and print all primes between the integers specified on a line.
doLine :: [Integer] -> StrL.ByteString -> IO ()
doLine factors l = mapM_ print $ primesForLine factors l
---------------------- pure code below this line ------------------------------
-- get all primes between the integers specified on a line.
primesForLine :: [Integer] -> StrL.ByteString -> [Integer]
primesForLine factors l = getPrimes factors range
where
range = rangeForLine l
-- Generate a list of numbers to check, store it in list, and then check them...
getPrimes :: [Integer] -> (Integer, Integer) -> [Integer]
getPrimes factors range = filter (isPrime factors) (getCandidates range)
-- generate list of candidate values based on upper and lower bound
getCandidates :: (Integer, Integer) -> [Integer]
getCandidates (propStart, propEnd) = list
where
list = if propStart < 3
then 2 : oddList
else oddList
oddList = [listStart, listStart + 2 .. propEnd]
listStart = if cleanStart `rem` 2 == 0
then cleanStart + 1
else cleanStart
cleanStart = if propStart < 3
then 3
else propStart
-- A line always has the lower and upper bound separated by a space.
rangeForLine :: StrL.ByteString -> (Integer, Integer)
rangeForLine caseLine = start `seq` end `seq` (start, end)
where
[start, end] = (map readInteger $ StrL.words caseLine)::[Integer]
-- read an Integer from a ByteString
readInteger :: StrL.ByteString -> Integer
readInteger x =
case StrL.readInteger x of Just (i,_) -> i
Nothing -> error "Unparsable Integer"
-- read an Int from a ByteString
readInt :: StrL.ByteString -> Int
readInt x =
case StrL.readInt x of Just (i,_) -> i
Nothing -> error "Unparsable Int"
-- generates all primes in a lazy way.
allPrimes :: [Integer]
allPrimes = ps (2:[3,5 .. ])
where
ps (np:candidates) = -- np stands for New Prime
np : ps (filter (\n -> n `rem` np /= 0) candidates)
ps [] = error "this can't happen but is shuts up the compiler"
-- Check to see if it is a prime by comparing against the factors.
isPrime :: [Integer] -> Integer -> Bool
isPrime factors val = all (\f -> val `rem` f /= 0) validFactors
where
validFactors = takeWhile (< ceil) factors
ceil = ((ceiling $ sqrt $ ((fromInteger val)::Double))) :: Integer
I have no idea how to fix this warning. How do I start? Do I compile to assembly and match the error up? What does the warning even mean?
These are just (annoying) warnings, indicating that GHC could do further specializations to your code if you really want to. Future versions of GHC will likely not emit this data by default, since there's nothing you can do about it anyway.
They are harmless, and are not errors. Don't worry about them.
To directly address the problem, you can use -w (suppress warnings) instead of -Wall.
E.g. in a file {-# OPTIONS_GHC -w #-} will disable warnings.
Alternately, increasing the specialization threshold will make the warning go away, e.g. -fspec-constr-count=16

Resources