为什么这种无点形式会导致编译错误?

时间:2020-01-01 18:19:51

标签: haskell pointfree

虽然我在玩discord-haskell软件包中的乒乓球示例,却遇到一个奇怪的错误。

这里是原始代码,它以某种格式位于项目的README中。工作正常,没有错误。

我用^符号标记了,我将对其进行更改。

{-# LANGUAGE OverloadedStrings #-}  -- allows "string literals" to be Text

import Control.Monad (when)
import Data.Text (isPrefixOf, toLower, Text)
import Control.Concurrent (threadDelay)
import qualified Data.Text.IO as TIO

import Discord
import Discord.Types
import qualified Discord.Requests as R

-- | Replies "pong" to every message that starts with "ping"
pingpongExample :: IO ()
pingpongExample = do
    userFacingError <- runDiscord $ def { discordToken = "", discordOnEvent = eventHandler }
    TIO.putStrLn userFacingError

eventHandler :: DiscordHandle -> Event -> IO ()
eventHandler dis event = case event of
    MessageCreate m -> when (not (fromBot m) && isPing (messageText m)) $ do
        _ <- restCall dis (R.CreateReaction (messageChannel m, messageId m) "eyes")
             ^^^^^^^^^^^^
        threadDelay (4 * 10 ^ 6)
        _ <- restCall dis (R.CreateMessage (messageChannel m) "Pong!")
             ^^^^^^^^^^^^
        pure ()
    _ -> pure ()

fromBot :: Message -> Bool
fromBot m = userIsBot (messageAuthor m)

isPing :: Text -> Bool
isPing = ("ping" `isPrefixOf`) . toLower

我想用restCall dis前面的(R.createXXX)代替。这是我编辑的代码。还标记发生编译错误的地方。

{-# LANGUAGE OverloadedStrings #-}  -- allows "string literals" to be Text

import Control.Monad (when)
import Data.Text (isPrefixOf, toLower, Text)
import Control.Concurrent (threadDelay)
import qualified Data.Text.IO as TIO

import Discord
import Discord.Types
import qualified Discord.Requests as R

-- | Replies "pong" to every message that starts with "ping"
main :: IO ()
main = do
    userFacingError <- runDiscord $ def { discordToken = "", discordOnEvent = eventHandler }
    TIO.putStrLn userFacingError

eventHandler :: DiscordHandle -> Event -> IO ()
eventHandler dis event = case event of
    MessageCreate m -> when (not (fromBot m) && isPing (messageText m)) $ do
        _ <- foo (R.CreateReaction (messageChannel m, messageId m) "eyes")
        threadDelay (4 * 10 ^ 6)
        _ <- foo (R.CreateMessage (messageChannel m) "Pong!")
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        pure ()
    _ -> pure ()

  where
    foo x = restCall dis x   -- works fine when this line is uncommented
    -- foo = restCall dis    -- compile error when this line is uncommented


fromBot :: Message -> Bool
fromBot m = userIsBot (messageAuthor m)

isPing :: Text -> Bool
isPing = ("ping" `isPrefixOf`) . toLower

当带有参数形式的函数运行良好时(除了hlint建议使用无点样式)。 ghcide将dis推导为DiscordHandle,将restCall推导为DiscordHandle -> r a -> IO (Either RestCallErrorCode a)

没有参数,GHC抱怨类型。

compile error pic

和以前一样,disDiscordHandle,但是restCall被推导为DiscordHandle -> ChannelRequest () -> IO (Either RestCallErrorCode ())

这怎么会发生?我认为自由点形式始终与带有参数样式的函数相同。

0 个答案:

没有答案