>>>flip fix (0 :: Int) (\a b -> putStrLn "abc")
Output: "abc"
To jest uproszczona wersja korzystania z flip fix
.
Widziałem ten sposób użycia go w niektórych filmach na youtube, które prawdopodobnie pochodzą z google tech talk lub innych rozmów.haskell - odwróć fix/fix
Czy ktoś może mi dać kilka wskazówek (nie jakiś adres pamięci, dzięki!), Że to co jest dokładnie fix
. Znam ogólną definicję z dokumentacji na oficjalnej stronie. I przeskanowałem wiele rzeczy w Internecie, po prostu nie mogłem znaleźć odpowiedzi, która byłaby obszerna i łatwa do zrozumienia.
I flip fix
właśnie wygląda dla mnie tajemnicą. Co tak naprawdę stało się w tym konkretnym wywołaniu funkcji?
BTW, ja tylko podniósł Haskell się jak 2 miesiące temu. I nie jestem bardzo dobry w matematyce :(
To jest kompletny kod, udostępniane przez osobę, która zrobiła prezentację, jeśli ktoś jest zainteresowany:
(Oh, a oto link wiki wyjaśniając grę mastermind
Click)
module Mastermind where
import Control.Monad
import Data.Function
import Data.List
import System.Random
data Score = Score
{ scoreRightPos :: Int
, scoreWrongPos :: Int
}
deriving (Eq, Show)
instance Read Score where
readsPrec _ r = [ (Score rp wp, t)
| (rp, s) <- readsPrec 11 r
, (wp, t) <- readsPrec 11 s
]
calcScore :: (Eq a) => [a] -> [a] -> Score
calcScore secret guess = Score rightPos wrongPos
where
rightPos = length [() | (a, b) <- zip secret guess, a == b]
wrongPos = length secret - length wrongTokens - rightPos
wrongTokens = guess \\ secret
pool :: String
pool = "rgbywo"
universe :: [String]
universe = perms 4 pool
perms :: Int -> [a] -> [[a]]
perms n p = [s' | s <- subsequences p, length s == n, s' <- permutations s]
chooseSecret :: IO String
chooseSecret = do
i <- randomRIO (0, length universe - 1)
return $ universe !! i
guessSecret :: [Score] -> [String]-> [String]
guessSecret _ [] = []
guessSecret ~(s:h) (g:u) = g : guessSecret h [g' | g' <- u, calcScore g' g == s]
playSecreter :: IO()
playSecreter = do
secret <- chooseSecret
flip fix (0 :: Int) $ \loop numGuesses -> do
putStr "Guess: "
guess <- getLine
let
score = calcScore secret guess
numGuesses' = numGuesses + 1
print score
case scoreRightPos score of
4 -> putStrLn $ "Well done, you guessed in " ++ show numGuesses'
_ -> loop numGuesses'
playBoth :: IO()
playBoth = do
secret <- chooseSecret
let
guesses = guessSecret scores universe
scores = map (calcScore secret) guesses
history = zip guesses scores
forM_ history $ \(guess, score) -> do
putStr "Guess: "
putStrLn guess
print score
putStrLn $ "Well done, you guessed in " ++ show (length history)
playGuesser :: IO()
playGuesser = do
input <- getContents
let
guesses = guessSecret scores universe
scores = map read $ lines input
history = zip guesses scores
forM_ guesses $ \guess -> do
putStrLn guess
putStr "Score: "
case snd $ last history of
Score 4 0 -> putStrLn $ "Well done me, I guessed in " ++ show (length history)
_ -> putStrLn "Cheat!"
FYI, rozmowa dotyczyła wdrożenia gry Mastermind, której autorem jest Peter Marks w London Haskell Users 'Group. –
Tak, jest. @TomEllis – prM