는 this excellent blog post에서 다음 단축 코드를 살펴 보자 :이 순환 회귀는 어떻게 원하는 결과를 제공합니까?
import System.Random (Random, randomRIO)
newtype Stream m a = Stream { runStream :: m (Maybe (NonEmptyStream m a)) }
type NonEmptyStream m a = (a, Stream m a)
empty :: (Monad m) => Stream m a
empty = Stream $ return Nothing
cons :: (Monad m) => a -> Stream m a -> Stream m a
cons a s = Stream $ return (Just (a, s))
fromList :: (Monad m) => [a] -> NonEmptyStream m a
fromList (x:xs) = (x, foldr cons empty xs)
하지 나쁘지까지 - 모나드, 재귀 데이터 구조 및 목록에서 하나를 구축하는 방법. 내가 마지막 네 줄에서 일어나는 무한의 신비 순환을 잘 파악하고 있지 않다
select :: NonEmptyStream IO a -> IO a
select (a, s) = select' (return a) 1 s where
select' :: IO a -> Int -> Stream IO a -> IO a
select' a n s = do
next <- runStream s
case next of
Nothing -> a
Just (a', s') -> select' someA (n + 1) s' where
someA = do i <- randomRIO (0, n)
case i of 0 -> return a'
_ -> a
:
이제 일정한 메모리를 사용하여 스트림에서 (균일) 임의 요소를 선택이 기능을 고려 ; 결과 a'
은 someA
에서 재귀에 따라 달라지며, 은에 따라 달라질 수 있습니다. 단, 반드시에 따라 다르지만 반드시 그런 것은 아닙니다.
회귀 작업자가 어쨌든 IO a
어큐뮬레이터의 잠재적 인 값을 누적하고 있다는 느낌이 들지만, 분명히 그것에 대해 충분히 추론 할 수는 없습니다.
누구든지이 기능이 어떻게 작동하는 지에 대한 설명을 제공 할 수 있습니까?
마지막 두 개의 재귀 호출이'xs' 대신'xs''을 사용해서는 안됩니까? – is7s
@ is7s : 물론 감사합니다. – hammar