I want to combine my two functions into one? - haskell

I have two functions:
firstfunc :: (RandomGen g) => g -> Int -> Float -> [[Int]]
firstfunc rnd n p = makGrid $ map (\t -> if t <= p then 1 else 0) $ take (n*n) (randoms rnd)
where makGrid rnd = unfoldr nextRow (rnd, n)
nextRow (_, 0) = Nothing
nextRow (es, i) = let (rnd, rest) = splitAt n es in Just (rnd, (rest, i-1))
sndfunc firstfunc = head $ do
lst <- firstfunc
return $ map (\x -> if (x == 0) then 2 else x) lst
let newFunc = ((firstfunc .) .) . sndfunc
main = do
gen <- getStdGen
let g = (firstfunc gen 5 0.3)
print g
let h = sndfunc g
print h
print $ newFunc gen 5 0.3
The firstfunc takes two values like 5 and 0.3 and returns a list of lists like: [[0,0,0,1,0],[1,0,0,1,0],[0,0,1,1,0],[0,0,0,0,0],[1,0,0,0,1]]
The sndfunc takes the head of the above list of lists, which is [1,0,0,1,0] from the above example, and replaces the zeroes with 2s like this: [1,2,2,1,2].
Is there a way to combine the two functions such that the firstfunc only returns something like: [[1,2,2,1,2],[0,0,1,1,0],[0,0,0,0,0],[1,0,0,0,1]]?
ERROR:
getting parse error parse error (possibly incorrect indentation or mismatched brackets) on this line: let newFunc = ((firstfunc .) .) . sndfunc
2nd EDIT:
prac.hs:15:32:
Couldn't match type ‘[b]’ with ‘a -> a1 -> b0’
Expected type: [[b]] -> a -> a1 -> b0
Actual type: [[b]] -> [b]
Relevant bindings include
newFunc :: [[b]] -> a -> a1 -> Int -> Float -> [[Int]]
(bound at prac.hs:15:1)
In the second argument of ‘(.)’, namely ‘sndfunc’
In the expression: (((firstfunc .) .) . sndfunc)
Failed, modules loaded: none.

You can either use
print $ sndfunc $ firstfunc gen 5 0.3
or you can define a new function
let newFunc = ((sndfunc .) .) . firstfunc
and use that.
print $ newFunc gen 5 0.3
(the extra (.) operators are needed because firstfunc takes three inputs).

Related

Composing arbitrarily many maps in Haskell

How is it possible to compose n maps in Haskell?
I've tried doing it recursively:
composeMap 0 f = (\x -> x)
composeMap n f = (.) f (composeMap (n-1) f)
And iteratively:
composeMap' n k f g =
if n == k then g
else composeMap' n (k+1) f (f . g)
composeMap n f = composeMap' n 0 f (\x -> x)
But to no avail. Haskell thinks I am constructing an infinite type.
This is obviously false as the function defined is finite for any
n >= 0.
Any suggestions?
Some have posted solutions treating f as having the following type signature:
f :: a -> a
However, I want this to work for f s.t. f is polymorphic in the following way:
f :: a -> a'
f :: a' -> a''
In particular, I want a function that works for the function map, with possible type signatures:
map :: (a -> b) -> [a] -> [b]
map (polymorphic) :: ([a] -> [b]) -> [[a]] -> [[b]]
The function compiles perfectly fine, but Haskell infers the following type signature, which is not what I want:
composeMap'' :: Int -> (b -> b) -> b -> b
I've even tried wrapping map in a monad, but Haskell still thinks I'm constructing an infinite type:
composeMap n f = foldl (>>=) f (replicate n (\x -> return (map x)))
Edit:
I got what I want with the following template Haskell code. Pretty sweet.
This is for declaring the composed map functions:
composeMap :: Int -> Q Dec
composeMap n
| n >= 1 = funD name [cl]
| otherwise = fail "composeMap: argument n may not be <= 0"
where
name = mkName $ "map" ++ show n
composeAll = foldl1 (\fs f -> [| $fs . $f |])
funcs = replicate n [| map |]
composedF = composeAll funcs
cl = clause [] (normalB composedF) []
This is for inlining the composed map. It is more flexible:
composeMap :: Int -> Q Exp
composeMap n = do
f <- newName "f"
maps <- composedF
return $ LamE [(VarP f)] (AppE maps (VarE f))
where
composeAll = foldl1 (\fs f -> [| $fs . $f |])
funcs = replicate n [| map |]
composedF = composeAll funcs
Also, the guys who put the question on hold didn't even understand the question in the first place...
I am afraid I am missing something. Your first implementation compiles and works fine for me (ghc 8.0.2).
Your second implementation failed to compile because you forgot the ' in the else clause. Here is my complete source file:
composeMap1 0 f = (\x -> x)
composeMap1 n f = (.) f (composeMap1 (n-1) f)
composeMap2' n k f g =
if n == k then g
else composeMap2' n (k+1) f (f . g)
composeMap2 n f = composeMap2' n 0 f (\x -> x)
And some tests
λ: :l question.hs
[1 of 1] Compiling Main ( question.hs, interpreted )
Ok, modules loaded: Main.
λ: doubleQuote = composeMap1 2 (\x -> "'" ++ x ++ "'")
λ: doubleQuote "something"
"''something''"
λ: doubleQuote = composeMap2 2 (\x -> "'" ++ x ++ "'")
λ: doubleQuote "something"
"''something''"
λ: plusThree = composeMap1 3 (+1)
λ: plusThree 10
13
λ: plusThree = composeMap2 3 (+1)
λ: plusThree 10
13

Replace only the head of the list in haskell?

I have a list like: [[0,0,0,1,0],[1,0,0,1,0],[0,0,1,1,0],[0,0,0,0,0],[1,0,0,0,1]] and I want to replace the head of this list, which is [0,0,0,1,0], with something like [2,2,2,1,2], to get [[2,2,2,1,2],[1,0,0,1,0],[0,0,1,1,0],[0,0,0,0,0],[1,0,0,0,1]]. How can I do that?
EDIT:
I have this function, returning [[0,0,0,1,0],[1,0,0,1,0],[0,0,1,1,0],[0,0,0,0,0],[1,0,0,0,1]], I want it to return [[2,2,2,1,2],[1,0,0,1,0],[0,0,1,1,0],[0,0,0,0,0],[1,0,0,0,1]].
firstfunc :: (RandomGen g) => g -> Int -> Float -> [[Int]]
firstfunc rnd n p = makGrid $ map (\t -> if t <= p then 1 else 0) $ take (n*n) (randoms rnd)
where makGrid rnd = unfoldr nextRow (rnd, n)
nextRow (_, 0) = Nothing
nextRow (es, i) = let (rnd, rest) = splitAt n es in Just (rnd, (rest, i-1))
change 0 = 2
change x = x
replace (x:rest) = map change x:rest
If you want a general way to transform the head of a list you could create a function:
transformHead :: (a -> a) -> [a] -> [a]
transformHead _ [] = []
transformHead f (x:xs) = (f x):xs
then you could use it to transform the result from firstFunc e.g.
transformHead (map (\x -> 2 - x)) $ firstfunc gen c p

Couldn't match expected type `Bool' with actual type `IO Bool'

I'm trying to write a prime number generator and utilizing MillerRabin formula check whether or not the number is prime before it returns the number back into me.
Here is my code below:
primegen :: Int -> IO Integer
primegen bits =
fix $ \again -> do
x <- fmap (.|. 1) $ randomRIO (2^(bits - 1), 2^bits - 1)
if primecheck x then return x else again
primesTo100 = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97]
powerMod :: (Integral a, Integral b) => a -> a -> b -> a
powerMod m _ 0 = 1
powerMod m x n | n > 0 = join (flip f (n - 1)) x `rem` m where
f _ 0 y = y
f a d y = g a d where
g b i | even i = g (b*b `rem` m) (i `quot` 2)
| otherwise = f b (i-1) (b*y `rem` m)
witns :: (Num a, Ord a, Random a) => Int -> a -> IO [a]
witns x y = do
g <- newStdGen
let r = [9080191, 4759123141, 2152302898747, 3474749600383, 341550071728321]
fs = [[31,73],[2,7,61],[2,3,5,7,11],[2,3,5,7,11,13],[2,3,5,7,11,13,17]]
if y >= 341550071728321
then return $ take x $ randomRs (2,y-1) g
else return $ snd.head.dropWhile ((<= y).fst) $ zip r fs
primecheck :: Integer -> IO Bool
primecheck n | n `elem` primesTo100 = return True
| otherwise = do
let pn = pred n
e = uncurry (++) . second(take 1) . span even . iterate (`div` 2) $ pn
try = return . all (\a -> let c = map (powerMod n a) e in
pn `elem` c || last c == 1)
witns 100 n >>= try
I don't understand whats going on with the IO Bool. And I'm getting the following error...
Couldn't match expected type `Bool' with actual type `IO Bool'
In the return type of a call of `primecheck'
In the expression: primecheck x
In a stmt of a 'do' block: if primecheck x then return x else again
If I change the IO Bool to just a normal Bool, they will give me this:
Couldn't match expected type `Bool' with actual type `m0 a0'
Thanks for the help guys! I appreciate it.
if primecheck x then return x else again
is not valid because primecheck x returns a value of type IO Bool. You want to sequence the monad with do notation or something like:
primecheck x >>= (\val -> if val then return x else again)
Since primecheck returns IO Bool, when you call it in primegen, you need to sequence it rather than calling it like a pure function.
primegen :: Int -> IO Integer
primegen bits =
fix $ \again -> do
x <- fmap (.|. 1) $ randomRIO (2^(bits - 1), 2^bits - 1)
success <- primecheck x
if success then return x else again

Haskell: What is the difference between (+1) and (\x->x+1)?

Is there a difference between these two functions?
ghct says:
Prelude> :t (+1)
(+1) :: Num a => a -> a
Prelude> :t \x->x+1
\x->x+1 :: Num a => a -> a
But
When I used (+1) syntax in this piece of code:
data B = B {
pos :: Int,
cells :: [Int]
} deriving (Show)
createB :: Int -> B
createB n = B 0 (take n $ repeat 0)
size :: B -> Int
size b = length $ cells b
get_curr :: B -> Int
get_curr b = (cells b) !! (pos b)
apply :: (Int -> Int) -> B -> B
apply f b = let n = pos b
h = take n $ cells b -- head
t = drop (n + 1) $ cells b -- tail
in B n $ h ++ [f (get_curr b)] ++ t
-- ...
eval :: [Char] -> StateT B IO ()
eval [] = return ()
eval (x:xs) = do
b <- get
put $ case x of
'+' -> apply (+1) b
'-' -> apply (-1) b
'>' -> fwd b
'<' -> back b
otherwise -> b
-- ...
prelude (as well as compiler) said:
> :load BrainFuck.hs
[1 of 1] Compiling BrainFuck ( BrainFuck.hs, interpreted )
BrainFuck.hs:49:40:
No instance for (Num (Int -> Int))
arising from the literal `1'
Possible fix: add an instance declaration for (Num (Int -> Int))
In the expression: 1
In the first argument of `apply', namely `(- 1)'
In the expression: apply (- 1) b
Failed, modules loaded: none.
What am I doing wrong?
sorry if code is not-so-cool (full source here: https://github.com/nskeip/bf/blob/a755b2d27292593d63fe1e63c2a6e01cebc73520/BrainFuck.hs)
This code:
(-1)
... doesn't mean the same thing as this code:
\ x -> x - 1
- is a special case in Haskell; it is the only prefix operator in the language. When you write (-1), you get "negative one" which is a number, and not "subtract one" which is a function.
You should use subtract 1 to get what you need.
Your problem is not with (+1), it's with (-1):
Prelude> :t (-1)
(-1) :: Num a => a
-1 is a number! Try with apply (\x -> x-1) b or apply (subtract 1) b.
There is no difference between (+1) and \x -> x + 1 and if you look closely, (+1) isn't what's causing your error. (-1) is. And that's because unlike (+1), (-1) is not an operator section, it's negative one.
Instead of subtract the decrement expression can be written directly also as (+(-1)) .

haskell function declaration

I have been playing around with haskell and I found out that if I write the following function in a code file:
f :: Int -> [a] -> a
f idx str = last $ (take . succ) idx str
then this works totally fine. Naturally, I figured the code would look better without the arguments.
f :: Int -> [a] -> a
f = last $ (take . succ)
But this generates an error when I try to load it into gchi
Couldn't match expected type `[a]'
against inferred type `Int -> [a1] -> [a1]'
In the second argument of `($)', namely `(take . succ)'
In the expression: last $ (take . succ)
In the definition of `f': f = last $ (take . succ)
Failed, modules loaded: none.
I'm kind of confused about how this could be happening...
You're misunderstanding the precedence. This:
f idx str = last $ (take . succ) idx str
Is parsed like this:
f idx str = last $ ( (take . succ) idx str )
Not (as you think) like this:
f idx str = ( last $ (take . succ) ) idx str
$ has extremely the lowest precedence of any operator, and function calling has extremely the highest. . has the second highest, so (take . succ) binds to it's arguments (idx str) before it binds to last $.
Furthermore, the function (as it compiles) doesn't do what it looks like you want it to do. It increments idx, then takes that character from the string. If that's what you want, why use succ when (+1) works? You've already restricted the type to integers.
As written, your function is identical to the !! operator - it's just an array index function. Is this what you want? Or do you want to succ the item at the given index? You could accomplish that with the following:
f :: Enum a => Int -> [a] -> a
f idx str = succ $ str !! idx
-- or
f idx str = succ $ (!!) str idx
-- or, only one argument
f idx = succ . (!! idx)
I'm still working on a version with no written arguments. Perhaps it's more important to write working code? ;)
This is what happens when you try to compose last with (take . succ)
:t (.)
(.) :: (b -> c) -> (a -> b) -> a -> c
last :: [t] -> t ~ (b -> c)
-- so b ~ [t] and c ~ t
(take . succ) :: Int -> [t] -> [t]
-- so a ~ int and b ~ [t] -> [t]
Type of b is inferred to be [t] from last but it couldn't match against the type of b in (take . succ) which is [t] -> [t]
f idx str = last $ (take . succ) idx str
-- applying definition of ($)
f idx str = last ((take . succ) idx str)
-- adding parentheses for clarity
f idx str = last (((take . succ) idx) str)
-- using definition of (.)
f idx str = (last . (take . succ) idx) str
-- η-conversion
f idx = last . (take . succ) idx
-- infix to prefix notation
f idx = (.) last ((take . succ) idx)
-- ading parentheses for clarity
f idx = ((.) last) ((take . succ) idx)
-- using definition of (.)
f idx = ((.) last . (take . succ)) idx
-- η-conversion
f = (.) last . (take . succ)
-- remove parentheses: (.) is right-associative
f = (.) last . take . succ

Resources