I am new to both USB drivers and Haskell. I am trying to connect to Tomu (an ARM micocontroller that fits in a USB port) using System.USB. I tried this example: https://github.com/basvandijk/usb-example/blob/master/example.hs, but it is several years out of date. I am trying to do hello world on USB, but getting type errors.
The following code works:
module Lib where
import System.USB
import System.USB.IO
import Data.Vector
import Data.Maybe
getOneDesc :: Int -> IO (VendorId, ProductId)
getOneDesc n = do
usbConn <- newCtx
devList <- getDevices usbConn
f <- getDeviceDesc $ devList ! n
let f0 = deviceVendorId f
let f1 = deviceProductId f
return (f0, f1)
At the repl, I can type getOneDesc 0 and I get something like this:
(300, 42)
I figured I ought to be able to do something like this:
isThisDeviceTheOneIWant :: Int -> VendorId -> ProductId -> Bool
isThisDeviceTheOneIWant n a b = do
(x, y) <- getOneDesc n
return (x == a) && (y == b)
But I encounter type errors.
Can anybody see what's wrong with this?
Your getOneDesc is an IO (VendorId, ProductId), so that means that the result type of your return (x == a) && (y == b) has type IO Bool. So you should change the type of your function. You must also add parentheses around the argument you pass to return (because in Haskell, return is not a keyword, just a plain function).
isThisDeviceTheOneIWant :: Int -> VendorId -> ProductId -> IO Bool
isThisDeviceTheOneIWant n a b = do
(x, y) <- getOneDesc n
return ((x == a) && (y == b))
You can not make the isThisDeviceTheOneIWant return a Bool, since the getOneDesc returns an IO (VendorId, ProductId), and you can not get an a out of an IO a.
We can, like #DanielWagner says, use fmap :: Functor f => (a -> b) -> f a -> f b to process the result of the getOneDesc n, like:
isThisDeviceTheOneIWant :: Int -> VendorId -> ProductId -> IO Bool
isThisDeviceTheOneIWant n a b = fmap ((a, b) ==) (getOneDesc n)
or use (<$>) :: Functor f => (a -> b) -> f a -> f b which is the same as fmap:
isThisDeviceTheOneIWant :: Int -> VendorId -> ProductId -> IO Bool
isThisDeviceTheOneIWant n a b = ((a, b) ==) <$> getOneDesc n
Related
I am trying to understand hmap.
module Main where
import Control.Effect.Fresh
import Control.Effect.Carrier
a :: Fresh Maybe Int
a = Fresh (\n -> Just 5)
b :: Fresh Maybe [Int]
b = fmap (\n -> [7::Int]) a
f :: Maybe Int -> [] Int
f mi = [1]
c :: Fresh Maybe Int -> Fresh [] Int
c = hmap f
main :: IO ()
main = do
putStrLn "Just testing types"
ghc error:
• Couldn't match type ‘x’ with ‘Int’
‘x’ is a rigid type variable bound by
a type expected by the context:
forall x. Maybe x -> [x]
at src/Main.hs:16:5-10
Expected type: Maybe x -> [x]
Actual type: Maybe Int -> [Int]
• In the first argument of ‘hmap’, namely ‘f’
In the expression: hmap f
In an equation for ‘c’: c = hmap f
|
16 | c = hmap f
| ^
Why is there no match of x with Int?
The type signature of hmap is:
hmap :: Functor m => (forall x . m x -> n x) -> (h m a -> h n a)
My f function is declared in my code as:
f :: Maybe Int -> [] Int
f mi = [1]
Why is there no match between m x -> n x and Maybe Int -> [] Int
As you can see from the signature of hmap, it expects a function of type forall x. m x -> n x. The forall x in there means that it needs to work for all possible x, but your function only works for Int. It has the type m Int -> n Int (where m=Maybe and n=[]), but hmap requires m x -> n x for all possible x.
In order to use f with hmap, you need to define it in a generic way, such that it works for any argument type, for example
f :: forall x. Maybe x -> [] x
f (Just x) = [x]
f Nothing = []
(NOTE: forall x. is not necessary in this signature, but I included it to illustrate how f needs to match the first argument of hmap)
hmap has NOT this type
hmap :: Functor m => (m x -> n x) -> (h m a -> h n a)
but has this type instead:
hmap :: Functor m => (forall x . m x -> n x) -> (h m a -> h n a)
The difference is that, in the first (fake) type, you can choose the value of x. In the latter type, instead x is chosen by hmap (and not by you).
In your code, you pass f to hmap, which amounts to choosing x = Int, but you are not allowed to do that. You need to define an f which is able to work with any x, e.g.
f :: Maybe x -> [] x
f mi = []
I came across the paper "https://www.cs.ox.ac.uk/jeremy.gibbons/publications/iterator.pdf" which has code examples in quite an abstract pseudo haskell syntax.
I'm struggeling to implement the example from section 6.2. in real haskell.
This is how far I came:
module Iterator where
import Data.Functor.Const -- for Const
import Data.Monoid (Sum (..), getSum) -- for Sum
import Control.Monad.State.Lazy -- for State
import Control.Applicative -- for WrappedMonad
data Prod m n a = Prod {pfst:: m a, psnd:: n a} deriving (Show)
instance (Functor m, Functor n) => Functor (Prod m n) where
fmap f (Prod m n) = Prod (fmap f m) (fmap f n)
instance (Applicative m, Applicative n) => Applicative (Prod m n) where
pure x = Prod (pure x) (pure x)
mf <*> mx = Prod (pfst mf <*> pfst mx) (psnd mf <*> psnd mx)
-- Functor Product
x :: (Functor m, Functor n) => (a -> m b) -> (a -> n b) -> (a -> Prod m n b)
(f `x` g) y = Prod (f y) (g y)
type Count = Const (Sum Integer)
count :: a -> Count b
count _ = Const 1
cciBody :: Char -> Count a
cciBody = count
cci :: String -> Count [a]
cci = traverse cciBody
lciBody :: Char -> Count a
lciBody c = Const (Sum $ test (c == '\n'))
test :: Bool -> Integer
test b = if b then 1 else 0
lci :: String -> Count [a]
lci = traverse lciBody
clci :: String -> Prod Count Count [a]
clci = traverse (cciBody `x` lciBody)
-- up to here the code is working
-- can't get this to compile:
wciBody :: Char -> (WrappedMonad (Prod (State Bool) Count)) a
wciBody c = pure $ state (updateState c) where
updateState :: Char -> Bool -> (Integer, Bool)
updateState c w = let s = c /= ' ' in (test (not(w && s)), s)
wci :: String -> (WrappedMonad (Prod (State Bool) Count)) [a]
wci = traverse wciBody
clwci :: String -> (Prod (Prod Count Count) (WrappedMonad (Prod (State Bool) Count))) [a]
clwci = traverse (cciBody `x` lciBody `x` wciBody)
str :: [Char]
str = "hello \n nice \t and \n busy world"
iteratorDemo = do
print $ clci str
print $ clwci str
The problematic spot is wciBody where I have no idea how to implement the ⇑ function from the paper.
Any ideas?
I think you may be mis-translating between the infix type operators used in the paper with the prefix type constructors in your definitions. I say this because the paper contains
wciBody :: Char → (𝕄 (State Bool) ⊡ Count) a
You have translated this as
wciBody :: Char -> (WrappedMonad (Prod (State Bool) Count)) a
which I don't think makes sense: Prod x y has no Monad instance, so it makes no sense to wrap it in WrapMonad. Rather, you are intended to read the ⊡ character as separating its entire left half (𝕄 (State Bool)) from its right half (Count), similar to how value-level operators in Haskell parse:
wciBody :: Char -> Prod (WrappedMonad (State Bool)) Count a
This makes more sense, doesn't it? Prod now takes three arguments, the first two of which are each of kind * -> *, and WrappedMonad's argument is clearly a monad. Does this change get you back on track?
Thanks to the hint by amalloy I finally got the example code working.
Here is what I came up with:
module Iterator where
import Data.Functor.Product -- Product of Functors
import Data.Functor.Compose -- Composition of Functors
import Data.Functor.Const -- Const Functor
import Data.Functor.Identity -- Identity Functor (needed for coercion)
import Data.Monoid (Sum (..), getSum) -- Sum Monoid for Integers
import Control.Monad.State.Lazy -- State Monad
import Control.Applicative -- WrappedMonad
import Data.Coerce (coerce) -- Coercion magic
-- Functor Product
(<#>) :: (Functor m, Functor n) => (a -> m b) -> (a -> n b) -> (a -> Product m n b)
(f <#> g) y = Pair (f y) (g y)
-- Functor composition
(<.>) :: (Functor m, Functor n) => (b -> n c) -> (a -> m b) -> (a -> (Compose m n) c)
f <.> g = Compose . fmap f . g
type Count = Const (Sum Integer)
count :: a -> Count b
count _ = Const 1
cciBody :: Char -> Count a
cciBody = count
cci :: String -> Count [a]
cci = traverse cciBody
lciBody :: Char -> Count a
lciBody c = Const $ test (c == '\n')
test :: Bool -> Sum Integer
test b = Sum $ if b then 1 else 0
lci :: String -> Count [a]
lci = traverse lciBody
clci :: String -> Product Count Count [a]
clci = traverse (cciBody <#> lciBody)
wciBody :: Char -> Compose (WrappedMonad (State Bool)) Count a
wciBody c = coerce (updateState c) where
updateState :: Char -> Bool -> (Sum Integer, Bool)
updateState c w = let s = not(isSpace c) in (test (not w && s), s)
isSpace :: Char -> Bool
isSpace c = c == ' ' || c == '\n' || c == '\t'
wci :: String -> Compose (WrappedMonad (State Bool)) Count [a]
wci = traverse wciBody
clwci :: String -> (Product (Product Count Count) (Compose (WrappedMonad (State Bool)) Count)) [a]
clwci = traverse (cciBody <#> lciBody <#> wciBody)
-- | the actual wordcount implementation.
-- for any String a triple of linecount, wordcount, charactercount is returned
wc :: String -> (Integer, Integer, Integer)
wc str =
let raw = clwci str
cc = coerce $ pfst (pfst raw)
lc = coerce $ psnd (pfst raw)
wc = coerce $ evalState (unwrapMonad (getCompose (psnd raw))) False
in (lc,wc,cc)
pfst :: Product f g a -> f a
pfst (Pair fst _) = fst
psnd :: Product f g a -> g a
psnd (Pair _ snd) = snd
main = do
putStrLn "computing three counters in one go"
print $ wc "hello \n world"
I am trying to test my implementation of zipWith using QuickCheck. My implementation, myZipWith, I would like to QuickCheck test by comparing to the standard function. Something like:
main = do
quickCheck (prop_myZipWith :: (Int -> Int -> Int) -> [Int] -> [Int] -> Bool)
prop_myZipWith :: (a -> b -> c) -> [a] -> [b] -> Bool
prop_myZipWith f x y = (myZipWith x y) == (zipWith f x y)
This does not work because (Int -> Int -> Int) is not an instance of Arbitrary.
With single-argument functions one can get around this using Test.QuickCheck.Function's Fun (which instantiates Arbitrary). For example:
main = do
quickCheck (prop_myMap :: Fun Int Int -> [Int] -> Bool)
prop_myMap :: Fun a b -> [a] -> Bool
prop_myMap (Fun _ f) l = (myMap f l) == (map f l)
I am trying to do something similar except generating two-argument arbitrary functions.
How can I generate arbitrary instances of two argument functions for QuickCheck testing of higher-order functions such as zipWith?
QuickCheck 2.9.2
With QuickCheck 2.9.2, you can use the Fun type, and the Fn pattern. You'll have to
import Test.QuickCheck.Function
You can then write the property using a tuple as input, and then curry the function:
prop_myZipWith :: Eq c => Fun (a, b) c -> [a] -> [b] -> Bool
prop_myZipWith (Fn f) x y = myZipWith (curry f) x y == zipWith (curry f) x y
main looks like this:
main =
quickCheck (prop_myZipWith :: Fun (Int, Int) Int -> [Int] -> [Int] -> Bool)
This compiles, and the test passes, in my repro.
QuickCheck 2.10.0.1
With QuickCheck 2.10.0.1, you can instead use the Fn2 pattern, like this:
prop_myZipWith :: Eq c => Fun (a, b) c -> [a] -> [b] -> Bool
prop_myZipWith (Fn2 f) x y = myZipWith f x y == zipWith f x y
The main method remains the same, because the type of prop_myZipWith hasn't changed, but import Test.QuickCheck.Function is no longer required.
I have a these three functions
a :: Int -> Maybe Int
a i = if i < 100 then Just i else Nothing
b :: Int -> Maybe Int
b i = if i < 50 then Just i else Nothing
c :: Int -> Maybe Int
c i = if i > 0 then Just i else Nothing
And I want to chain them together so that when the result of one function results in a Nothing the input of that function is returned instead.
I can achieve this with this function:
import Data.Maybe (fromMaybe)
e :: Int -> [Int -> Maybe Int] -> Int
e i [] = i
e i (f:fs) = e (fromMaybe i $ f i) fs
-
*Main> e 75 [a,b,c]
75
Is there an existing function, Monad instance, or other way in the base libraries that exhibits this behavior?
Expanding my comment above -- this approach is not too different from the code the OP posted.
We first define how to turn a function a -> Maybe a into a -> a, substituting the input for Nothing.
totalize :: (a -> Maybe a) -> (a -> a)
totalize f x = fromMaybe x (f x)
Then, we exploit the above: we make every function "total" (meaning no-Nothings), wrap it as an Endo, then we compose the list of endomorphisms (mconcat is composition in the Endo monoid).
e :: [a -> Maybe a] -> a -> a
e = appEndo . mconcat . map (Endo . totalize)
or even (as suggested below)
e :: Foldable t => t (a -> Maybe a) -> a -> a
e = appEndo . foldMap (Endo . totalize)
Well, you can create a a -> a from a a -> Maybe a:
repair :: (a -> Maybe a) -> a -> a
repair f x = fromMaybe x (f x)
Afterwards, you can just combine (.) and repair:
andThen :: (a -> Maybe a) -> (a -> Maybe a) -> a -> a
andThen f g = repair g . repair f
But there's no library function for that, since there is no general way to get a value out of a Monad.
Are you looking for the maybe monad?
*Main> let f x = a x >>= b >>= c >> return x
*Main> f 1
Just 1
*Main> f 100
Nothing
*Main>
Then if the result is Nothing we can get to your desired end state with fromMaybe (or just maybe and id, same thing):
*Main> let g x = maybe x id (f x)
*Main> g 100
100
I was reviewing some code and came across the following gem, which I'd wager is a copy-paste of pointfree output:
(I thought the following would more appropriate than the usual foo/bar for this particular question :P)
import Control.Monad (liftM2)
data Battleship = Battleship { x :: Int
, y :: Int
} deriving Show
placeBattleship :: Int -> Int -> Battleship
placeBattleship x' y' = Battleship { x = x', y = y' }
coordinates :: Battleship -> (Int, Int)
coordinates = liftM2 (,) x y
Would someone be kind enough to explain the steps needed to simplify from: (i) coordinates b = (x b, y b) to: (ii) coordinates = liftM2 (,) x y? In particular, I'm a bit confused as to the use of liftM2 as I wasn't even aware that a monad was lurking in the background.
I know that (i) can also be represented as: coordinates s = (,) (x s) (y s) but I'm not sure where/how to proceed.
P.S. The following is why I suspect it's from pointfree (output is from GHCI and :pl is aliased to pointfree):
λ: :pl coordinates s = (x s, y s)
coordinates = liftM2 (,) x y
This takes advantage of the Monad instance for (->) r, also called the "reader monad". This is the monad of functions from a specific type to a. (Take a look here for motivation on why it exists in the first place.)
To see how it works for various functions, replace m with (r -> in m a. For example, if we just do liftM, we get:
liftM :: (a -> b) -> (m a -> m b)
liftM :: (a -> b) -> ((r -> a) -> (r -> b))
:: (a -> b) -> (r -> a) -> (r -> b) -- simplify parentheses
...which is just function composition. Neat.
We can do the same thing for liftM2:
liftM2 :: (a -> b -> c) -> m a -> m b -> m c
liftM2 :: (a -> b -> c) -> (r -> a) -> (r -> b) -> (r -> c)
So what we see is a way to compose two one-argument functions with a two-argument function. It's a way of generalizing normal function composition to more than one argument. The idea is that we create a function that takes a single r by passing that through both of the one-argument functions, getting two arguments to pass into the two-argument function. So if we have f :: (r -> a), g :: (r -> b) and h :: (a -> b -> c), we produce:
\ r -> h (f r) (h r)
Now, how does this apply to your code? (,) is the two-argument function, and x and y are one-argument functions of the type Battleship -> Int (because that's how field accessors work). With this in mind:
liftM2 (,) x y = \ r -> (,) (x r) (y r)
= \ r -> (x r, y r)
Once you've internalized the idea of multiple function composition like this, point-free code like this becomes quite a bit more readable—no need to use the pointfree tool! In this case, I think the non-pointfree version is still better, but the pointfree one isn't terrible itself.
The monad liftM2 is working over here is the function monad (->) a. This is equivalent to the Reader monad, as you may have seen before.
Recall the definition of liftM2:
liftM2 :: Monad m => (a -> b -> r) -> m a -> m b -> m r
liftM2 f ma mb = do
a <- ma
b <- mb
return $ f a b
So now if we substitute in (,) for f, x for ma, and y for mb, we get
liftM2 (,) x y = do
a <- x
b <- y
return $ (,) a b
Since x, y :: Battleship -> Int which is equivalent to ((->) Battleship) Int, then m ~ (->) Battleship. The function monad is defined as
instance Monad ((->) a) where
return x = const x
m >>= f = \a -> f (m a) a
Essentially what the function monad does is allow you to extract the output from several functions provided they all have the same input. A more clear example might be something like
test = do
a <- (^2)
b <- (^3)
c <- (^4)
d <- show
return (a, b, c, d)
> test 2
(4, 8, 16, "2")
You could easily rewrite
data Battleship = Battleship { x :: Int
, y :: Int
} deriving Show
placeBattleship :: Int -> Int -> Battleship
placeBattleship x y = Battleship x y
coordinates :: Battleship -> (Int, Int)
coordinates (Battleship x y) = (x, y)
It isn't point-free style, but quite simple