lomeo: (лямбда)
[personal profile] lomeo
Не очень понимаю, как сделать некоторые вычисления eager. Кто знает, подскажите.
Допустим у меня есть простой шелл - State с одной целой переменной. В шелле поддерживается две команды
  • r - прочесть целое значение

  • w - вывести целое значение

Вот код:

import Control.Monad.State
import Data.Char

type TestShell = StateT Int IO ()

cmdRead :: String -> TestShell
cmdRead x =
    do let i = read x
       put i
       return ()

cmdWrite :: String -> TestShell
cmdWrite _ =
    do  i <- get
        liftIO (print i)
        return ()

runCycle i =
    do
        putStr "> "
        cmdLine <- getLine
        let (cmdName, arg) = break isSpace cmdLine
            arg' = dropWhile isSpace arg'
            cmd = case cmdName of
                    "r" -> cmdRead
                    "w" -> cmdWrite
        i' <- liftIO $ execStateT (cmd arg) i
        runCycle i'

main = runCycle 0



Теперь, собственно, вопрос. Допустим, я сделал ошибку при наборе числа и ввел не "r 123", а скажем "r xpen". Ошибку мне шелл покажет только после команды "w". Вот:

*Main> main
> r xpen
> w
*** Exception: Prelude.read: no parse
А как мне сделать, чтобы ошибка показывалась после ввода команды r?

Date: 2006-05-31 10:47 am (UTC)
nine_k: A stream of colors expanding from brain (Default)
From: [personal profile] nine_k
Вроде есть оператор "!", заставляющий вычислить выражение сейчас же?

Date: 2006-05-31 10:50 am (UTC)
From: [identity profile] thesz.livejournal.com
*Main> :t ($)
($) :: (a -> b) -> a -> b
*Main> :t ($!)
($!) :: (a -> b) -> a -> b
*Main> ($!) id (error "aaa")
*** Exception: aaa
*Main> ($) id (error "aaa")
*** Exception: aaa
*Main> ($) (const 10) (error "aaa")
10
*Main> ($!) (const 10) (error "aaa")
*** Exception: aaa
*Main>


Что надо сменить:

cmdRead :: String -> TestShell
cmdRead x =
    do let i = read x
       put $! i
       return ()


f $! x = форсировать x и вычислить (f x).

Date: 2006-05-31 11:07 am (UTC)
From: [identity profile] lomeo.livejournal.com
Спасибо! Я про $! знал, но что то не получалось. Уж куда я его только не прикладывал. В реальной программе, разумеется, сложный тип, а не Int, пришлось еще в самом типе ставить в одном месте $!, и еще в одном !. Но зато заработало!

Date: 2006-05-31 11:08 am (UTC)
From: [identity profile] lomeo.livejournal.com
этот тип так аннотируется, мол, при создании конструктором значения, этот параметр будет вычисляться форсированно.

а еще..

Date: 2006-06-23 08:50 am (UTC)
From: [identity profile] igor-ozerov.livejournal.com
а еще вроде как есть функция strict

Re: а еще..

Date: 2006-06-23 09:13 am (UTC)
From: [identity profile] lomeo.livejournal.com
где?

Profile

lomeo: (Default)
Dmitry Antonyuk

September 2025

S M T W T F S
 123456
78910111213
14 151617181920
21222324252627
282930    

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Feb. 26th, 2026 09:31 pm
Powered by Dreamwidth Studios