![](/img/trans.png)
[英]Are applicative functors composed with the applicative style really independent?
[英]Using Applicative instance of composed functors
我有兩種形式的功能
foo :: Int -> IO String
bar :: Int -> IO Integer
它基本上存在於由(->) Int
和IO
的組合給出的函子中。 現在,有一個類型的函數
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
需要一個String
和Integer
,而foo
返回一個IO String
並bar
一個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
。 因此,這是一個與foo
和bar
的輸出類型匹配的函數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.