I have the following code:
betaRest :: Int -> [Int] -> Int
betaRest n prevDigits | n == 0 = (length prevDigits)
| otherwise = (sum (map (betaRest (n - 1)) [0..9]))
betaFirst :: Int -> Int
betaFirst n | n == 0 = 0
| otherwise = (betaRest (n - 1) [1..9])
It gives me the following errors, and I don't know why.
1) No instance for (Enum [Int]) arising from the arithmetic sequence '0 .. 9'
2) No instance for (Num [Int]) arising from the literal '0'
Does Haskell think that things made with the ".." operator are enumerations? But why isn't there an error for the line that's 4 lines below (with "[1..9]") it then?
Edit: What I want the code to do is like this (procedurally):
int betaRest(int n, int[] prevDigits) {
if (n == 0) return prevDigits.length;
else {
sum = 0;
foreach prevDigit in prevDigits {
sum += betaRest(n - 1, [0..9]);
}
return sum;
}
}
int betaFirst(int n) {
if (n == 0) return 0;
else return betaRest(n - 1, [1..9]);
}
Thus, betaFirst(1) == 9, and betaFirst(2) == 90. Yes, somebody may want to suggest a formula for generating this, but I'm going to add a filter of some sort to [0..9], thus reducing the range.
You pass betaRest to map. Map is (a -> a) -> [a] -> [a] so for [Int] list you pass it it wants an Int -> Int function. But partially applied betaRest is [Int] -> Int.
As for [0..9] its type is (Enum t, Num t) => [t] and it's translated into enumFromTo 0 9 application. So compiler figured your error the other way around: if you define special Num and Enum instances for lists, so [0..9] becomes a list of lists of int, then your application will make sense.
But I think you want to use inits or tails function. Let us know what you want to achieve so we can help with solution.
A minimal fix to would be to add prevDigits as an argument to map and use a lambda abstraction to ignore unused prevDigit:
| otherwise = sum (map (\prevDigit -> betaRest (n - 1) [0..9]) prevDigits)
(sum (map (betaRest (n - 1)) [0..9]))
Let's reduce the number of parentheses to better be able to see what happens.
sum (map (betaRest (n - 1)) [0..9])
The argument of sum is
map (betaRest (n-1)) [0 .. 9]
Now, betaRest :: Int -> [Int] -> Int, hence the type of the partially applied function is
betaRest (n-1) :: [Int] -> Int
hence we can infer the type
map (betaRest (n-1)) :: [[Int]] -> [Int]
But the argument passed to map (betaRest (n-1)) is [0 .. 9], which has type
[0 .. 9] :: (Num a, Enum a) => [a]
The Num constraint comes from the use of an integer literal, and the Enum constraint from the use of the enumFromTo function (in its syntax-sugared form [low .. high]). Passing that as an argument to a function expecting an argument of type [[Int]] means the type variable a must be instantiated as [Int], and then the constraints need to be checked, i.e. the instances of [Int] for Num and Enum must be looked up. Neither of these exist, hence the error messages.
I'm not sure your procedural example is really what you want,
int betaRest(int n, int[] prevDigits) {
if (n == 0) return prevDigits.length;
else {
sum = 0;
foreach prevDigit in prevDigits {
sum += betaRest(n - 1, [0..9]);
}
return sum;
}
}
the foreach loop is much easier (and more efficiently) expressed as
sum = prevDigits.length * betaRest(n-1, [0 .. 9]);
so for the foreach to make sense, there should be a dependence on prevDigit in the loop body.
The translation to Haskell would be
betaRest n prevDigits
| n == 0 = length prevDigits
| otherwise = length prevDigits * betaRest (n-1) [0 .. 9]
-- or with the loop, with the small improvement that `betaRest (n-1) [0 .. 9]
-- is only computed once (if the Haskell implementation is sensible)
-- | otherwise = sum $ map (const $ betaRest (n-1) [0 .. 9]) prevDigits
But as stated above, I doubt that's really what you want.
Related
``
I'm a Haskell newbie and I'm defining a function that given an Int n it tells if a number is prime or not by searching for an 2<=m<=sqrt(n) that mod n m ==0
if such m exists, then n is not prime, if not then n is prime.
I'm trying to define a list with numbers m between 2 and sqrt n, that mod n m ==0
My thought is that if the list is empty then n is prime, it not, n is not prime
`
isprime' :: Int -> Bool
isprime' n | l == [] = True
| otherwise = False
where
l = [x|x<-[2.. sqrt n], mod n x == 0]
`
But there seems to be a problem with sqrt n when I run my code and I can't understand it. can someone explain what I'm doing wrong/what to change for my code to run/ and why there's an error?
Running the code gives the following error
test.hs:9:28: error:
• No instance for (Floating Int) arising from a use of ‘sqrt’
• In the expression: sqrt n
In the expression: [2 .. sqrt n]
In a stmt of a list comprehension: x <- [2 .. sqrt n]
|
9 | l = [x|x<-[2.. sqrt n], mod n x == 0]
| ^^^^^^
You are correct in saying that the error is with sqrt, but the rest is pretty opaque to a new Haskell developer. Lets try by checking the type of sqrt to see if that helps.
Prelude> :t sqrt
sqrt :: Floating a => a -> a
Here I'm using ghci to interactively write code. :t asks for the type of the preceeding expression. The line sqrt :: Floating a => a -> a says sqrt takes in some floating point number a and returns something of the same type.
Similar to our error message we see this Floating thing. this thing is a typeclass but for the sake of solving this problem we'll save understanding those for later. In essence, haskell is trying to tell you that Int is not floating point number which is what sqrt expects. We can amend that by turning our Int into a Float with fromIntegral which is a really general function for turning number types into one another. (see Get sqrt from Int in Haskell)
isprime' :: Int -> Bool
isprime' n | l == [] = True
| otherwise = False
where
asFloat :: Float -- new! - tell fromIntegral we want a float
asFloat = fromIntegral n -- new! turn n into a Float
l = [x|x<-[2..sqrt asFloat], mod n x == 0]
This also errors! but it's a new one!
test.hs:10:48: error:
• Couldn't match expected type ‘Int’ with actual type ‘Float’
• In the second argument of ‘mod’, namely ‘x’
In the first argument of ‘(==)’, namely ‘mod n x’
In the expression: mod n x == 0
|
10 | l = [x|x<-[2..sqrt asFloat], mod n x == 0]
| ^
this is saying that x is suddenly a Float. When we changed to [2..sqrt asFloat] we now have made a list of Floats ([Float]). We need to change that back to [Int]. we can do that by calling floor on the result of the square root.
isprime' :: Int -> Bool
isprime' n | l == [] = True
| otherwise = False
where
asFloat :: Float
asFloat = fromIntegral n
l = [x|x<-[2..floor (sqrt asFloat)], mod n x == 0] -- new! I added floor here to change the result of sqrt from a `Float` into a `Int`
This now correctly compiles.
I wrote my first program in Haskell today. It compiles and runs successfully. And since it is not a typical "Hello World" program, it in fact does much more than that, so please congrats me :D
Anyway, I've few doubts regarding my code, and the syntax in Haskell.
Problem:
My program reads an integer N from the standard input and then, for each integer i in the range [1,N], it prints whether i is a prime number or not. Currently it doesn't check for input error. :-)
Solution: (also doubts/questions)
To solve the problem, I wrote this function to test primality of an integer:
is_prime :: Integer -> Bool
is_prime n = helper n 2
where
helper :: Integer -> Integer -> Bool
helper n i
| n < 2 * i = True
| mod n i > 0 = helper n (i+1)
| otherwise = False
It works great. But my doubt is that the first line is a result of many hit-and-trials, as what I read in this tutorial didn't work, and gave this error (I suppose this is an error, though it doesn't say so):
prime.hs:9:13:
Type constructor `Integer' used as a class
In the type signature for `is_prime':
is_prime :: Integer a => a -> Bool
According to the tutorial (which is a nicely-written tutorial, by the way), the first line should be: (the tutorial says (Integral a) => a -> String, so I thought (Integer a) => a -> Bool should work as well.)
is_prime :: (Integer a) => a -> Bool
which doesn't work, and gives the above posted error (?).
And why does it not work? What is the difference between this line (which doesn't work) and the line (which works)?
Also, what is the idiomatic way to loop through 1 to N? I'm not completely satisfied with the loop in my code. Please suggest improvements. Here is my code:
--read_int function
read_int :: IO Integer
read_int = do
line <- getLine
readIO line
--is_prime function
is_prime :: Integer -> Bool
is_prime n = helper n 2
where
helper :: Integer -> Integer -> Bool
helper n i
| n < 2 * i = True
| mod n i > 0 = helper n (i+1)
| otherwise = False
main = do
n <- read_int
dump 1 n
where
dump i x = do
putStrLn ( show (i) ++ " is a prime? " ++ show (is_prime i) )
if i >= x
then putStrLn ("")
else do
dump (i+1) x
You are misreading the tutorial. It would say the type signature should be
is_prime :: (Integral a) => a -> Bool
-- NOT Integer a
These are different types:
Integer -> Bool
This is a function that takes a value of type Integer and gives back a value of type Bool.
Integral a => a -> Bool
This is a function that takes a value of type a and gives back a value of type Bool.
What is a? It can be any type of the caller's choice that implements the Integral type class, such as Integer or Int.
(And the difference between Int and Integer? The latter can represent an integer of any magnitude, the former wraps around eventually, similar to ints in C/Java/etc.)
The idiomatic way to loop depends on what your loop does: it will either be a map, a fold, or a filter.
Your loop in main is a map, and because you're doing i/o in your loop, you need to use mapM_.
let dump i = putStrLn ( show (i) ++ " is a prime? " ++ show (is_prime i) )
in mapM_ dump [1..n]
Meanwhile, your loop in is_prime is a fold (specifically all in this case):
is_prime :: Integer -> Bool
is_prime n = all nondivisor [2 .. n `div` 2]
where
nondivisor :: Integer -> Bool
nondivisor i = mod n i > 0
(And on a minor point of style, it's conventional in Haskell to use names like isPrime instead of names like is_prime.)
Part 1: If you look at the tutorial again, you'll notice that it actually gives type signatures in the following forms:
isPrime :: Integer -> Bool
-- or
isPrime :: Integral a => a -> Bool
isPrime :: (Integral a) => a -> Bool -- equivalent
Here, Integer is the name of a concrete type (has an actual representation) and Integral is the name of a class of types. The Integer type is a member of the Integral class.
The constraint Integral a means that whatever type a happens to be, a has to be a member of the Integral class.
Part 2: There are plenty of ways to write such a function. Your recursive definition looks fine (although you might want to use n < i * i instead of n < 2 * i, since it's faster).
If you're learning Haskell, you'll probably want to try writing it using higher-order functions or list comprehensions. Something like:
module Main (main) where
import Control.Monad (forM_)
isPrime :: Integer -> Bool
isPrime n = all (\i -> (n `rem` i) /= 0) $ takeWhile (\i -> i^2 <= n) [2..]
main :: IO ()
main = do n <- readLn
forM_ [1..n] $ \i ->
putStrLn (show (i) ++ " is a prime? " ++ show (isPrime i))
It is Integral a, not Integer a. See http://www.haskell.org/haskellwiki/Converting_numbers.
map and friends is how you loop in Haskell. This is how I would re-write the loop:
main :: IO ()
main = do
n <- read_int
mapM_ tell_prime [1..n]
where tell_prime i = putStrLn (show i ++ " is a prime? " ++ show (is_prime i))
I want to write a function which prints out a list of numbers from 1 to n: [1,2,...n], I know it can be done by [1..n] but I want to make my own function:
addtimes n = addtimes_ [] n
addtimes_ [lst] a =
if a < 1
then [lst]
else addtimes_ [a:lst] (a-1)
main =
print $ addtimes 10
Though above code compiles and runs, it gives following runtime error:
testing: testing.hs:(3,1)-(6,37): Non-exhaustive patterns in function addtimes_
Where is the problem and how can it be solved?
See the following, with corrected syntax (and type signatures added, seriously these are essential for both code documentation and for better error messages):
addtimes :: (Num a, Ord a) => a -> [a]
addtimes n = addtimes_ [] n
addtimes_ :: (Num a, Ord a) => [a] -> a -> [a]
addtimes_ lst a =
if a < 1
then lst
else addtimes_ (a:lst) (a-1)
main :: IO ()
main =
print $ addtimes 10
As well as referring to [lst] (a singleton list containing the one element lst) instead of lst (which can refer to anything, which in the context of your function must be a list, but can be of any length), you had put [a:lst] (again a singleton list, this time containing a list) instead of (a:lst), a list made up of first element a appended to the front of lst. (The parentheses are not needed for any syntactic reason, but are usually needed in practice, as in the above code, because of operator precedence: addtimes_ a:list (a-1) would be parsed as (addtimes_ a):(list (a-1)), which definitely isn't what you mean.
Edit:
To achieve what you want, now I understand your goal reading your
addtimes :: Int -> [Int]
addtimes 0 = []
addtimes n = if n > 0
then addtimes_ 1 n
else error "Doesn't work with negatives"
addtimes_ :: Int -> Int -> [Int]
addtimes_ m n = if n > m
then m : (addtimes_ (m+1) n)
else [n]
main =
print $ addtimes (10)
That will create a list with the numbers adding 1 consecutively
[1,2,3,4,5,6,7,8,9,10]
Here's a simple function. It takes an input Int and returns a (possibly empty) list of (Int, Int) pairs, where the input Int is the sum of the cubed elements of any of the pairs.
cubeDecomposition :: Int -> [(Int, Int)]
cubeDecomposition n = [(x, y) | x <- [1..m], y <- [x..m], x^3 + y^3 == n]
where m = truncate $ fromIntegral n ** (1/3)
-- cubeDecomposition 1729
-- [(1,12),(9,10)]
I want to test the property that the above is true; if I cube each element and sum any of the return tuples, then I get my input back:
import Control.Arrow
cubedElementsSumToN :: Int -> Bool
cubedElementsSumToN n = all (== n) d
where d = map (uncurry (+) . ((^3) *** (^3))) (cubeDecomposition n)
For runtime considerations, I'd like to limit the input Ints to a certain size when testing this with QuickCheck. I can define an appropriate type and Arbitrary instance:
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
import Test.QuickCheck
newtype SmallInt = SmallInt Int
deriving (Show, Eq, Enum, Ord, Num, Real, Integral)
instance Arbitrary SmallInt where
arbitrary = fmap SmallInt (choose (-10000000, 10000000))
And then I guess I have to define versions of the function and property that use SmallInt rather than Int:
cubeDecompositionQC :: SmallInt -> [(SmallInt, SmallInt)]
cubeDecompositionQC n = [(x, y) | x <- [1..m], y <- [x..m], x^3 + y^3 == n]
where m = truncate $ fromIntegral n ** (1/3)
cubedElementsSumToN' :: SmallInt -> Bool
cubedElementsSumToN' n = all (== n) d
where d = map (uncurry (+) . ((^3) *** (^3))) (cubeDecompositionQC n)
-- cubeDecompositionQC 1729
-- [(SmallInt 1,SmallInt 12),(SmallInt 9,SmallInt 10)]
This works fine, and the standard 100 tests pass as expected. But it seems unnecessary to define a new type, instance, and function when all I really need is a custom generator. So I tried this:
smallInts :: Gen Int
smallInts = choose (-10000000, 10000000)
cubedElementsSumToN'' :: Int -> Property
cubedElementsSumToN'' n = forAll smallInts $ \m -> all (== n) (d m)
where d = map (uncurry (+) . ((^3) *** (^3)))
. cubeDecomposition
Now, the first few times I ran this, everything worked fine, and all tests pass. But on subsequent runs I observed failures. Bumping up the test size reliably finds one:
*** Failed! Falsifiable (after 674 tests and 1 shrink):
0
8205379
I'm a bit confused here due to the presence of two shrunken inputs - 0 and 8205379 - returned from QuickCheck, where I would intuitively expect one. Also, those inputs work as predicted (on my show-able property, at least):
*Main> cubedElementsSumToN 0
True
*Main> cubedElementsSumToN 8205379
True
So it seems like obviously there's a problem in the property that uses the custom Gen I defined.
What have I done wrong?
I quickly realized that the property as I've written it is obviously incorrect. Here's the proper way to do it, using the original cubedElementsSumToN property:
quickCheck (forAll smallInts cubedElementsSumToN)
which reads quite naturally.
Task: "Sum the first 15,000,000 even numbers."
Haskell:
nats = [1..] :: [Int]
evens = filter even nats :: [Int]
MySum:: Int
MySum= sum $ take 15000000 evens
...but MySum takes ages. More precisely, about 10-20 times slower than C/C++.
Many times I've found, that a Haskell solution coded naturally is something like 10 times slower than C. I expected that GHC was a very neatly optimizing compiler and task such this don't seem that tough.
So, one would expect something like 1.5-2x slower than C. Where is the problem?
Can this be solved better?
This is the C code I'm comparing it with:
long long sum = 0;
int n = 0, i = 1;
for (;;) {
if (i % 2 == 0) {
sum += i;
n++;
}
if (n == 15000000)
break;
i++;
}
Edit 1: I really know, that it can be computed in O(1). Please, resist.
Edit 2: I really know, that evens are [2,4..] but the function even could be something else O(1) and need to be implemented as a function.
Lists are not loops
So don't be surprised if using lists as a loop replacement, you get slower code if the loop body is small.
nats = [1..] :: [Int]
evens = filter even nats :: [Int]
dumbSum :: Int
dumbSum = sum $ take 15000000 evens
sum is not a "good consumer", so GHC is not (yet) able to eliminate the intermediate lists completely.
If you compile with optimisations (and don't export nat), GHC is smart enough to fuse the filter with the enumeration,
Rec {
Main.main_go [Occ=LoopBreaker]
:: GHC.Prim.Int# -> GHC.Prim.Int# -> [GHC.Types.Int]
[GblId, Arity=1, Caf=NoCafRefs, Str=DmdType L]
Main.main_go =
\ (x_aV2 :: GHC.Prim.Int#) ->
let {
r_au7 :: GHC.Prim.Int# -> [GHC.Types.Int]
[LclId, Str=DmdType]
r_au7 =
case x_aV2 of wild_Xl {
__DEFAULT -> Main.main_go (GHC.Prim.+# wild_Xl 1);
9223372036854775807 -> n_r1RR
} } in
case GHC.Prim.remInt# x_aV2 2 of _ {
__DEFAULT -> r_au7;
0 ->
let {
wild_atm :: GHC.Types.Int
[LclId, Str=DmdType m]
wild_atm = GHC.Types.I# x_aV2 } in
let {
lvl_s1Rp :: [GHC.Types.Int]
[LclId]
lvl_s1Rp =
GHC.Types.:
# GHC.Types.Int wild_atm (GHC.Types.[] # GHC.Types.Int) } in
\ (m_aUL :: GHC.Prim.Int#) ->
case GHC.Prim.<=# m_aUL 1 of _ {
GHC.Types.False ->
GHC.Types.: # GHC.Types.Int wild_atm (r_au7 (GHC.Prim.-# m_aUL 1));
GHC.Types.True -> lvl_s1Rp
}
}
end Rec }
but that's as far as GHC's fusion takes it. You are left with boxing Ints and constructing list cells. If you give it a loop, like you give it to the C compiler,
module Main where
import Data.Bits
main :: IO ()
main = print dumbSum
dumbSum :: Int
dumbSum = go 0 0 1
where
go :: Int -> Int -> Int -> Int
go sm ct n
| ct >= 15000000 = sm
| n .&. 1 == 0 = go (sm + n) (ct+1) (n+1)
| otherwise = go sm ct (n+1)
you get the approximate relation of running times between the C and the Haskell version you expected.
This sort of algorithm is not what GHC has been taught to optimise well, there are bigger fish to fry elsewhere before the limited manpower is put into these optimisations.
The problem why list fusion can't work here is actually rather subtle. Say we define the right RULE to fuse the list away:
import GHC.Base
sum2 :: Num a => [a] -> a
sum2 = sum
{-# NOINLINE [1] sum2 #-}
{-# RULES "sum" forall (f :: forall b. (a->b->b)->b->b).
sum2 (build f) = f (+) 0 #-}
(The short explanation is that we define sum2 as an alias of sum, which we forbid GHC to inline early, so the RULE has a chance to fire before sum2 gets eliminated. Then we look for sum2 directly next to the list-builder build (see definition) and replace it by direct arithmetic.)
This has mixed success, as it yields the following Core:
Main.$wgo =
\ (w_s1T4 :: GHC.Prim.Int#) ->
case GHC.Prim.remInt# w_s1T4 2 of _ {
__DEFAULT ->
case w_s1T4 of wild_Xg {
__DEFAULT -> Main.$wgo (GHC.Prim.+# wild_Xg 1);
15000000 -> 0
};
0 ->
case w_s1T4 of wild_Xg {
__DEFAULT ->
case Main.$wgo (GHC.Prim.+# wild_Xg 1) of ww_s1T7 { __DEFAULT ->
GHC.Prim.+# wild_Xg ww_s1T7
};
15000000 -> 15000000
}
}
Which is nice, completely fused code - with the sole problem that we have a call to $wgo in a non-tail-call position. This means that we aren't looking at a loop, but actually at a deeply recursive function, with predictable program results:
Stack space overflow: current size 8388608 bytes.
The root problem here is that the Prelude's list fusion can only fuse right folds, and computing the sum as a right fold directly causes the excessive stack consumption.
The obvious fix would be to use a fusion framework that can actually deal with left folds, such as Duncan's stream-fusion package, which actually implements sum fusion.
Another solution would be to hack around it - and implement the left fold using a right fold:
main = print $ foldr (\x c -> c . (+x)) id [2,4..15000000] 0
This actually produces close-to-perfect code with current versions of GHC. On the other hand, this is generally not a good idea as it relies on GHC being smart enough to eliminate the partially applied functions. Already adding a filter into the chain will break that particular optimization.
Sum first 15,000,000 even numbers:
{-# LANGUAGE BangPatterns #-}
g :: Integer -- 15000000*15000001 = 225000015000000
g = go 1 0 0
where
go i !a c | c == 15000000 = a
go i !a c | even i = go (i+1) (a+i) (c+1)
go i !a c = go (i+1) a c
ought to be the fastest.
If you want to be sure to traverse the list only once, you can write the traversal explicitly:
nats = [1..] :: [Int]
requiredOfX :: Int -> Bool -- this way you can write a different requirement
requiredOfX x = even x
dumbSum :: Int
dumbSum = dumbSum' 0 0 nats
where dumbSum' acc 15000000 _ = acc
dumbSum' acc count (x:xs)
| requiredOfX x = dumbSum' (acc + x) (count + 1) xs
| otherwise = dumbSum' acc (count + 1) xs
First, you can be clever as young Gauss was and compute the sum in O(1).
Fun stuff aside, your Haskell solution uses lists. I'm quite sure your C/C++ solution doesn't. (Haskell lists are very easy to use so one is tempted to use them even in cases where it might not be appropriate.) Try benchmarking this:
sumBy2 :: Integer -> Integer
sumBy2 = f 0
where
f result n | n <= 1 = result
| otherwise = f (n + result) (n - 2)
Compile it using GHC with -O2 argument. This function is tail-recursive so compiler can implement it very efficiently.
Update: If you want it using even function, it's possible:
sumBy2 :: Integer -> Integer
sumBy2 = f 0
where
f result n | n <= 0 = result
| even n = f (n + result) (n - 1)
| otherwise = f result (n - 1)
You can also easily make the filtering function a parameter:
sumFilter :: (Integral a) => (a -> Bool) -> a -> a
sumFilter filtfn = f 0
where
f result n | n <= 0 = result
| filtfn n = f (n + result) (n - 1)
| otherwise = f result (n - 1)
Strict version works much faster:
foldl' (+) 0 $ take 15000000 [2, 4..]
Another thing to note is that nats and evens are so-called Constant Applicative Forms, or CAFs for short. Basically, those correspond to top-level definitions without any arguments. CAFs are a bit of an odd duck, for instance being the reason for the Dreaded Monomorphism Restriction; I'm not sure the language definition even allows CAFs to be inlined.
In my mental model of how Haskell executes, by the time dumbSum returns a value, evens will be evaluated to look something like 2:4: ... : 30000000 : <thunk> and nats to 1:2: ... : 30000000 : <thunk>, where the <thunk>s represent something that's not been looked at yet. If my understanding is correct, these allocations of : do have to happen and can't be optimized away.
So one way of speeding things up without altering your code too much would be to simply write:
dumbSum :: Int
dumbSum = sum . take 15000000 . filter even $ [1..]
or
dumbSum = sum $ take 15000000 evens where
nats = [1..]
evens = filter even nats
On my machine, compiled with -O2, that alone seems to result in a roughly 30% speedup.
I'm no GHC connaisseur (I've never even profiled a Haskell program!), so I could be wildly off the mark, though.