如何正确选择要连接的USB设备?

Jam*_*ter 3 haskell

我是USB驱动程序和Haskell的新手。我正在尝试使用System.USB连接到Tomu(适合USB端口的ARM微控制器)。我尝试了以下示例:https : //github.com/basvandijk/usb-example/blob/master/example.hs,但是已经过时了几年。我正在尝试在USB上打个招呼,但出现类型错误。

以下代码有效:

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)
Run Code Online (Sandbox Code Playgroud)

在repl处,我可以键入getOneDesc 0,然后得到如下所示的内容:

(300, 42)
Run Code Online (Sandbox Code Playgroud)

我认为我应该能够做这样的事情:

isThisDeviceTheOneIWant :: Int -> VendorId -> ProductId -> Bool
isThisDeviceTheOneIWant n a b = do
    (x, y) <- getOneDesc n
    return (x == a) && (y == b)
Run Code Online (Sandbox Code Playgroud)

但是我遇到类型错误。

有人可以看到这是怎么回事吗?

Wil*_*sem 6

getOneDesc是一个IO (VendorId, ProductId),因此表示您的结果类型为return (x == a) && (y == b)类型IO Bool。因此,您应该更改函数的类型。您还必须在要传递的参数周围加上括号return(因为在Haskell中,return它不是关键字,而只是一个普通函数)。

isThisDeviceTheOneIWant :: Int -> VendorId -> ProductId -> IO Bool
isThisDeviceTheOneIWant n a b = do
    (x, y) <- getOneDesc n
    return ((x == a) && (y == b))
Run Code Online (Sandbox Code Playgroud)

您不能使isThisDeviceTheOneIWantreturn为a Bool,因为return为getOneDesc an IO (VendorId, ProductId),并且您也不aIO a能使an 退出

就像@DanielWagner所说的,我们可以使用fmap :: Functor f => (a -> b) -> f a -> f b来处理的结果getOneDesc n,例如:

isThisDeviceTheOneIWant :: Int -> VendorId -> ProductId -> IO Bool
isThisDeviceTheOneIWant n a b = fmap ((a, b) ==) (getOneDesc n)
Run Code Online (Sandbox Code Playgroud)

或使用(<$>) :: Functor f => (a -> b) -> f a -> f bfmap

isThisDeviceTheOneIWant :: Int -> VendorId -> ProductId -> IO Bool
isThisDeviceTheOneIWant n a b = ((a, b) ==) <$> getOneDesc n
Run Code Online (Sandbox Code Playgroud)