Побочные эффекты внутри объявления экземпляра - PullRequest
0 голосов
/ 29 апреля 2019

Скажем, я хотел создать оболочку для UTCTime :

data CustomDateStamp = CustomDateStamp
    { 
      stampValue :: UTCTime
    } deriving (Show, Eq, Ord, Typeable)

Теперь скажите, что я хочу создать для этого значение по умолчанию "сейчас", например

instance Default CustomDateStamp where
    def = CustomDateStamp getCurrentTime def

Это (очевидно) завершается с:

   • Couldn't match expected type ‘UTCTime’
                  with actual type ‘IO UTCTime’
    • In the first argument of ‘CustomDateStamp’, namely ‘getCurrentTime’
      In the expression: CustomDateStamp getCurrentTime def
      In an equation for ‘def’: def = CustomDateStamp getCurrentTime def
    |
98  |     def = CustomDateStamp getCurrentTime def
    |                   ^^^^^^^^^^^^^^

Мой вопрос: как я могу использовать побочные эффекты в определениях экземпляров?Это вообще возможно?Какой предпочтительный подход к такой ситуации?

Ответы [ 3 ]

4 голосов
/ 29 апреля 2019

В первом приближении: вы не можете этого сделать.Однажды в IO, всегда в IO (и уже есть экземпляр Default для IO a, который не делает то, что вы хотите).Придумай другой план.

2 голосов
/ 29 апреля 2019

Я бы добавил, что вы могли бы написать это для типа, для которого значение по умолчанию требует действия ввода-вывода,

instance {-# OVERLAPPING #-} Default (IO CustomDateStamp) where
    def = CustomDateStamp <$> getCurrentTime

(легко настраивается, например, для mtl-стека). Несколько противоречиво, потому что перекрытие непослушно.

РЕДАКТИРОВАТЬ: Требуется OVERLAPPING, IO CustomDateStamp является более конкретным, чем IO a, поэтому он должен выбрать этот экземпляр в области видимости.

0 голосов
/ 29 апреля 2019

С getCurrentTime :: IO UTCTime вы не можете просто позвонить. Нет функции с типом IO a -> a

За исключением unsafePerformIO (и других подобных вещей). Я настоятельно не рекомендую вам идти по этому пути.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...