1

我是 Elm 新手,作为一个实验,我试图以一定的速率一次显示一个字符串。我已经完成了这么多。但是,每当程序遇到句尾字符(句号、问号、interrobang 等)时,我想在输出中引入一个短暂的暂停。但是,我不知道如何使这种暂停发生。

这是我的工作代码(当然减去停顿):

import Time (..)
import Signal (..)
import Text (..)
import String

stringOut : String -> Float -> Signal String
stringOut str rate = let 
    t = round <~ (foldp (+) 0 <| (flip (/) rate) <~ fps 60)
  in flip String.left str <~ t

main = asText <~ stringOut "This is a string. Yeah?" (20*millisecond)

我最初的想法是我应该在 Time 模块中使用延迟功能,但我不确定在不以Signal Signal Int. 任何帮助,将不胜感激。谢谢!

4

1 回答 1

1

信号问题的信号

问题Signal (Signal x)通常来自使用或定义返回Signals 的函数。一般情况下最好避开这些。

问题与解决方案

现在,如果我正确理解了您想要的系统,您有一段静态文本,一个以一定速率滴答的计数器,在每个滴答声上都应该显示一个文本的新字符,但在某些表示句子结尾的字符处应该是暂停。

时间刻度是程序的基本输入。如果你计算的不仅仅是你在文本中的距离,你可以引入你的停顿。您需要跟踪您是否处于暂停状态以及暂停的距离。每次你打到一个句子的结尾时,你设置了暂停,每个滴答都会在暂停处吃掉以继续偏移到文本中。

代码

这可能有点矫枉过正,但我​​将程序的输入和状态形式化并以通常可扩展的风格编写它:

import Time
import Time (Time)
import Signal
import Signal (Signal, (<~))
import Text (asText)
import String
import List
import Graphics.Element (Element)

type alias Input = ()
type alias State = { text : String, offset : Int, delay : Int }

initialState : State
initialState = { text = "This is a string. Yeah?", offset = 0, delay = 0 }
stdRate : Time
stdRate = 50 * Time.millisecond
stdDelay : Int
stdDelay = 5
endOfSentence : List String
endOfSentence = [".", "?", "!"]

input : Signal Input
input = always () <~ Time.every stdRate

state : Signal State
state = Signal.foldp (always step) initialState input

step : State -> State
step state =
  let
    newChar = String.slice state.offset (state.offset+1) state.text
  in
    if| state.delay > 0 -> { state | delay <- state.delay-1 }
      | List.member newChar endOfSentence ->
        { state | offset <- state.offset + 1, delay <- stdDelay }
      | otherwise -> { state | offset <- state.offset + 1 }

view : State -> String
view { text, offset } = String.left offset text

main : Signal Element
main = asText << view <~ state
于 2015-02-14T15:26:26.080 回答