簡體   English   中英

使用組合函子的應用實例

[英]Using Applicative instance of composed functors

我有兩種形式的功能

foo :: Int -> IO String

bar :: Int -> IO Integer

它基本上存在於由(->) IntIO的組合給出的函子中。 現在,有一個類型的函數

baz :: String -> Integer -> Float

我想使用類似的應用語法將它提升到Int -> IO _上下文

foobarbaz :: Int -> IO Float
foobarbaz = baz <$> foo <*> bar

如果我這樣做,編譯器會對我大喊大叫

Couldn't match type `IO String' with `[Char]'
      Expected type: Int -> String
        Actual type: Int -> IO String

好像它試圖僅將應用實例用於(->) Int

我認為應用函子是組合的,所以我可以將應用實例用於組合函子。 我錯了嗎? 或者我應該向編譯器提供更多信息?

我還嘗試啟用TypeApplications來明確指定我想要使用的函子,但我意識到我不能寫(->) Int (IO _) 真的有辦法做到嗎?

我認為應用函子是組合的,所以我可以將應用實例用於組合函子。

這是正確的,但假設我們取f ~ (->) Int ,那么類型是(<$>) :: (a -> b) -> (Int -> a) -> (Int -> b) , 和(<*>) :: (Int -> (a -> b)) -> (Int -> a) -> (Int -> b) ,但這與類型不匹配,因為baz需要一個StringInteger ,而foo返回一個IO Stringbar一個IO Integer

你可以利用liftA2 :: Applicative f => (a -> b -> c) -> fa -> fb -> fc來提升baz函數來使用IO動作的結果:

import Control.Applicative(liftA2)

foobarbaz :: Int -> IO Float
foobarbaz = liftA2 baz <$> foo <*> bar

因此, liftA2將在這里將baz :: String -> Integer -> Float轉換為liftA2 baz :: IO String -> IO Integer -> IO Float 因此,這是一個與foobar的輸出類型匹配的函數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM