STã¢ããã¯ãªãå¤æ´å¯è½ãªåç §ãå¤ã¸æã¡åºããªãã®ã調ã¹ã¦ã¿ã
ãã®æ稿ã¯ãHaskell Advent Calendar 2019 ã®4æ¥ç®ã®è¨äºã§ããSTã¢ããã®ä»çµã¿ã«ã¤ãã¦æ¸ãã¾ãããåä¸ç´è åãã®å 容ã¨ãªã£ã¦ãã¾ãã
- ã¯ããã«
- STã¢ããã¨ã¯
- STã¢ããã®å
- STã¢ããã®ä½¿ç¨ä¾
- STã¢ããã§ä½¿ç¨ããããã¼ã¿åã¨å種é¢æ°
- å¤æ´å¯è½ãªåç §ãå¤ã¸æã¡åºããã¨ããã¨
- ã¨ã©ã¼ã¡ãã»ã¼ã¸ããèå¯ãã
- forallã®æ¢æ±
- STã¢ããã®ããªãã¯
- ãããã«
- è¨æ£å 容ï¼2019/12/06ï¼
- åèè³æ
ã¯ããã«
STã¢ããã¯ãå¤æ´å¯è½ãªåç §ã¨ç ´å£çä»£å ¥æä½ãæ±ãã¤ã¤ãããããã£ãä¸ç´ãªç¶æ ãå¤ã¸æã¡åºããªããã¨ãåã§ä¿è¨¼ããã¦ããã¢ããã§ãã
æè¿ãã®ãåã§ç¶æ ãå¤ã¸æã¡åºããªãä»çµã¿ãã«ã¤ãã¦èª¿ã¹ã¦ãã¦ããªãã»ã©ãªã¨æã£ãã®ã§ãä»åã¯ãã®ãããã®ãã¨ãæ¸ãããã¨æãã¾ãã
æµãã¨ãã¦ã¯ãæåã«STã¢ããã®æ¦è¦ã使ãæ¹ãç´¹ä»ãã¾ãã次ã«STã¢ãããæ¯ããéåãã©ã³ã¯Nå¤ç¸ã«è§¦ããããããã©ã®ããã«STã¢ããã®å®å ¨æ§ãæ¯ãã¦ããã®ãã解説ãã¦ããããã¨æãã¾ãã
ãªããå 容ã«èª¤ããããã¾ãããåªãããææããã ããã¨å¬ããã§ãã
STã¢ããã¨ã¯
STã¢ãã (strict state-transformer monad) ã¯ãç¶æ ãæ±ãã¢ããã§ããããã§è¨ãç¶æ ã¨ã¯ãå½ä»¤åè¨èªã®ããã«å¤æ´å¯è½ãªåç §ãæå³ãã¦ãã¾ãããã®å¤æ´å¯è½ãªåç §ã«å¯¾ãã¦ç ´å£çä»£å ¥ãç¹°ãè¿ããªããè¨ç®çµæãæ±ãã¦ããã®ããSTã¢ããã®ç¹å¾´ã§ãã
ã¨ããã§ãåãç¶æ ãæ±ãã¢ããã«Stateã¢ãããããã¾ããæ¯è¼ããã¨ãStateã¢ããã¯æ´æ°ã®åº¦ã«é½åº¦æ°ããç¶æ ãä½æããã®ã«å¯¾ãã¦ãSTã¢ããã¯ç¶æ ã®ä½¿ãåããã§ããã®ã§ãå¦çå¹ççã«ã¯STã¢ããã®æ¹ãæå©ã§ããä¾ãã°å·¨å¤§ãªãã¼ã¿æ§é ãç¶æ ã¨ãã¦æ±ãå ´åã¯ããã®å·®ãéãããããªãã§ããããã
ãã®ããã«å¹ççã ãã©ä¸ç´ãªæ±ãä»äºãæ±ãSTã¢ããã§ãããæ±ãã¦ããã®ã¯ã¢ããã¢ã¯ã·ã§ã³ã®ä¸ã ãã§ããã¢ããã¢ã¯ã·ã§ã³ããæçµçã«åºåãããè¨ç®çµæã¯ãã¡ããã¨ç´ç²ãªå¤ã¨ãã¦åãåºããã¨ãã§ãã¾ãã
STã¢ããã®é¢ç½ãã¨ããã¯ããã®ä¸ç´ãªç¶æ ãå¤ã¸æã¡åºããã¨ãã§ããªããã¨ãããã¨ãåã§ä¿è¨¼ããã¦ããç¹ã§ããç¡çã«æã¡åºããã¨ãã¦ãåæ¤æ»ã§æããã¾ãã
å¤æ´å¯è½ãªåç §ãå¤ã¸æ¼ãåºããã¨ããªããã°ãä»ã®å ´æã§æå³ããå¤æ´ããã¦ãã¾ãå¿é ã¯ãªããªãã¾ãããã
STã¢ããã®å
ããã§ã¯ã¾ããSTã¢ããã®åã確èªãã¦ããã¾ãããã
ST s a
å³ãããåå¤æ° a
ã¯å¤ã表ããåå¤æ° s
ã¯ã¹ã¬ããï¼state threadï¼ã表ãã¾ãã
ãã®ã¹ã¬ããã表ã s
ã¯ãSTã¢ããã®ä¸ã ãã§çåããPhantom Typeã§ããPhantom Typeã¨ãããã¨ã¯ãå®è¡æã«ã¯åå¨ããªãããã©åæ¤æ»æã«ã¯åå¨ããåãã¨ãããã¨ã«ãªãã¾ãããæãæ¹ã¨ãã¦ã¯ããSTã¢ãããé§åããããã«å
é¨çã«å°ç¨ã¹ã¬ãããä½ããããã§ãããã¯å®è¡æã§ã¯ãªãåæ¤æ»æã«ãã¿ãããªæãæ¹ã§è¯ãã¨æãã¾ãã
ä½è«ã§ãããThinking with Types ã¨ããæ¸ç±ã§ã¯ãSTã¢ãããã
æ¬è³ªçã«ã¯ãphantom s parameterãæã£ãåãªãIdentity Monadã ã
ã¨è§£èª¬ãã¦ãã¾ãã
-- ST Monad ST s a -- Identity Monad Identity a
STã¢ããã®ä½¿ç¨ä¾
次ã«ãSTã¢ããã使ç¨ããç°¡åãªä¾ãè¦ã¦ã¿ã¾ãããã
import Control.Monad import Control.Monad.ST import Data.STRef sum' :: [Int] -> Int sum' xs = runST $ do ref <- newSTRef 0 forM_ xs $ \i -> do modifySTRef ref (+ i) readSTRef ref main :: IO () main = print $ sum' [1..10] -- çµæ: 55
sum'
ã¯ãInt
ã®ãªã¹ããåãåããéè¨ããçµæã Int
ã¨ãã¦è¿ãé¢æ°ã§ããå
é¨ã§ã¯ãSTã¢ããã使ç¨ãã¦ç ´å£ç代å
¥ãç¹°ãè¿ããªããè¨ç®çµæãæ±ãã¦ãã¾ããSTã¢ããã使ç¨ãã¦ããç¯å²ãé¢æ° sum'
ã®ä¸ã«éå®ããã¦ãããã¨ã«æ³¨ç®ãã¦ãã ããã
ã§ã¯ãé¢æ° sum'
ãããå°ã詳ããè¦ã¦ã¿ã¾ãããã
ã¾ããdoæ§æã®ä¸ã§æåã«ç»å ´ãã newSTRef
ã¯ãåæå¤ãä¸ããã¨å¤æ´å¯è½ãªåç
§ STRef
ãæã¤STã¢ãããä½æãã¾ããã¤ã¾ããref <- newSTRef 0
ã¯ãåæå¤ 0
ãä¸ãã¦STã¢ãããä½æãããããã STRef
ãåãåºã㦠ref
ã«æç¸ãã¦ãããã¨ã«ãªãã¾ãã以éãã® ref
ã¯ç¶æ
ãæ±ãåç
§åã¨ãã¦ä½¿ç¨ãã¾ãã
次㫠forM_ xs $ \i -> do
ã§ãå¼æ° xs
ã®åè¦ç´ ãå
é ããé çªã« i
ã¸æç¸ãã modifySTRef ref (+ i)
ã§ãåç
§å ref
ã«å¯¾ã㦠(+ i)
ã®è¨ç®çµæãç ´å£çã«ä»£å
¥ãã¦ãã¾ãã
modifySTRef
ã«ããç ´å£ç代å
¥ãçµããã¨ã readSTRef ref
ã§ãåç
§å ref
ããå¤ãèªã¿åããæå¾ã«doæ§æã®å¤ã§ runST
ã«ãã£ã¦ç´ç²ãªå¤ãåãåºãã¦ãã¾ãã
ãã®ããã«ãSTã¢ããã®åç §åã«å¯¾ããç ´å£çä»£å ¥ã¨ããæ±ãä»äºã¯ãã¢ããã¢ã¯ã·ã§ã³ã®ä¸ã§å®å ¨ã«éãè¾¼ãããã¦ãã¦ãæå¾ã«è¨ç®ããçµæã ããåãåºãããã¨ãåããã¾ããã
STã¢ããã§ä½¿ç¨ããããã¼ã¿åã¨å種é¢æ°
ããã§ãå ã»ã©ã®STã¢ããã®ä½¿ç¨ä¾ã§ç»å ´ãããã¼ã¿åãããã¨å種é¢æ°ã®ã·ã°ããã£ã確èªãã¦ããã¾ãããã
Data.STRef
Data.STRef
ã¯ãSTã¢ããã§å¤æ´å¯è½ãªåç
§ã¨ãã¦æ±ãããç ´å£ç代å
¥ãå¤ã®èªã¿è¾¼ã¿ã®éã«å¿
è¦ã¨ãªããã¼ã¿åã§ãã
STRef s a
ãªããåå¤æ° s
ã¨a
ã¯ãå
ã»ã©ç´¹ä»ããST s a
ã®åå¤æ°ã¨åãå½¹å²ã«ãªãã¾ãã
newSTRef
åæå¤ãä¸ãã¦ãåæç¶æ
ã®åç
§å STRef s a
ãæã¤STã¢ãããä½æããé¢æ°ã§ãã
newSTRef :: a -> ST s (STRef s a)
åå¤æ° a
ã¯ãä¸ããå¼æ°ã«ãã£ã¦åã決ã¾ããåç
§å STRef
ã®å¤ã¨ãã¦è¨å®ããã¾ããã¾ããåå¤æ° s
ã¯ããã®æç¹ã§åã決å®ãããã®ãä½ãç¡ãã®ã§ãå¤ç¸åã®ã¾ã¾ã¹ã¬ããã¨ãã¦è¨å®ããã¾ãã
ãã ããã®çµæå ST s (STRef s a)
ã¯ã¡ãã£ã¨å¤ã§ãããST
ã«ã STRef
ã«ãã¹ã¬ããã表ãåå¤æ° s
ããã¾ãã
æ°æã¡æªãã¯æ®ãã¾ãããããã«ã¤ãã¦ã¯å¾ã»ã©è§£èª¬ãã¾ãã
modifySTRef
åç
§å STRef s a
ã«å¯¾ãã¦é¢æ° a -> a
ã§å¤ã®æ´æ°ããã¾ãã
modifySTRef :: STRef s a -> (a -> a) -> ST s ()
readSTRef
åç
§å STRef s a
ã®å¤ã¨ç¶æ
ãèªã¿åãã¾ãã
readSTRef :: STRef s a -> ST s a
runST
é¢æ° readSTRef
ã§èªã¿åã£ãå
容ããå¤ã ããåãåºãã¾ãããªããST s a
ã (forall s. ST s a)
ã¨ãªã£ã¦ããçç±ã¯å¾è¿°ãã¾ãã
runST :: (forall s. ST s a) -> a
å¤æ´å¯è½ãªåç §ãå¤ã¸æã¡åºããã¨ããã¨
ã§ã¯ãé¢æ° newSTRef
ã§å¤æ´å¯è½ãªåç
§ ST s (STRef s a)
ãçæããé¢æ° runST
㧠ST s a
ã® a
ã«è¨å®ããã¦ããåç
§å (STRef s a)
ãæã¡åºããã¨ãããã©ããªãã§ããããã
runST $ newSTRef 100
ããã¯åæ¤æ»ã«å¤±æãã以ä¸ã®ãããªã¨ã©ã¼ã¡ãã»ã¼ã¸ãåºåããã¾ãã
<interactive>:18:9: error: ⢠Couldn't match type âaâ with âSTRef s Integerâ because type variable âsâ would escape its scope This (rigid, skolem) type variable is bound by a type expected by the context: forall s. ST s a at <interactive>:18:9-18 Expected type: ST s a Actual type: ST s (STRef s Integer) ⢠In the second argument of â($)â, namely ânewSTRef 100â In the expression: runST $ newSTRef 100 In an equation for âitâ: it = runST $ newSTRef 100 ⢠Relevant bindings include it :: a (bound at <interactive>:18:1)
ãªãã»ã©ãå¤æ´å¯è½ãªåç
§ (STRef s a)
ãã¢ããã®å¤ã¸æã¡åºããã¨ã¯ã§ãã¾ãããã
ã¡ãªã¿ã«å
ã»ã©ã®ã¨ã©ã¼ã¡ãã»ã¼ã¸ã§ã¯ã Couldn't match type âaâ with âSTRef s Integerâ because type variable âsâ would escape its scope
ã¨ãã¹ã¬ããã表ã s
ãã¹ã³ã¼ãã®å¤ã«åºããã¨ãã¦ããããåãåããªããã ãã¨è¨ã£ã¦ãã¾ããã¹ã³ã¼ãã£ã¦ä½ã§ããããï¼
ã¨ã©ã¼ã¡ãã»ã¼ã¸ããèå¯ãã
å
ã»ã©ã®ã¨ã©ã¼ã¡ãã»ã¼ã¸ãã forall s. ST s a
ãã¤ã¾ãé¢æ° runST
ã®ã·ã°ããã£ãéµãæ¡ã£ã¦ãããã§ãã
runST :: (forall s. ST s a) -> a
runST :: ST s a -> a
ãããªã㦠runST :: (forall s. ST s a) -> a
ã¨ãªã£ã¦ããã®ã¯ããªããªã®ã§ããããã
ããã§ãforall s .
ãå¤ãããã©ããªããå®é¨ãã¦ã¿ã¾ãããã以ä¸ã®ã³ã¼ãã¯ãThinking with Types ã§ç´¹ä»ããã¦ããã³ã¼ããå®é¨ç¨ã«æ¹å¤ãã¦ã¿ã¾ãããï¼ã³ã¼ãå
¨ä½ã¯ ãã¡ã ã«ãªãã¾ãï¼
runST' :: ST s a -> a -- `forall s .` ãåé¤ runST' = unsafeRunST foo :: STRef s Integer foo = runST' $ newSTRef 100
ããããã¨åæ¤æ»ã§æããããã¨ãªãå¤æ´å¯è½ãªåç
§ STRef s Integer
ãå¤ã¸æã¡åºãã¦ãã¾ãã¾ããï¼
ãã¯ããé¢æ° runST
ã®ã·ã°ããã£ãSTã¢ããã®å®å
¨æ§ãæ¯ããããã«éè¦ãªãã¨ãåããã¾ããã
ã§ã¯ããã® forall
ã£ã¦ä½ã§ããããã
forallã®æ¢æ±
éååã¯åã«éçãªæå³ãæããã
forall
ã®å½¹å²ãç¥ãããã«ãã¾ãã¯ä»¥ä¸ã®é¢æ°ãè¦ã¦ãã ããã
id :: a -> a id x = x
é¢æ° id
ã¯ãåå¤æ° a
ãåãåããã®ã¾ã¾è¿ãé¢æ°ã§ããæçé¢æ°ã¨ãããã¤ã§ãããå¼æ°ã¯å¤ç¸åãªã®ã§ã©ã®ãããªåã§ãåãåããã¨ãã§ãã¾ãã
ãã®ãã©ã®ãããªåã§ãããè¨èªæ¡å¼µã® ExplicitForAll
ã使ç¨ãã¦æ示çã«æ¸ãã¨ãã®ããã«ãªãã¾ãã
{-# LANGUAGE ExplicitForAll #-} id :: forall a. a -> a id x = x
ãã㧠forall
ãç»å ´ãã¾ãããã
ãã® forall
ã¯ãå
¨ç§°éååï¼universal quantifierãè¨å·ã¯â
ï¼ã¨å¼ã°ãããã®ã§ã修飾ããåå¤æ°ã«å¯¾ãã¦æåéãããã¹ã¦ã®ï¼for allï¼ãã¨ããéçãªæå³ãæããããã¨ãã§ãã¾ããã¤ã¾ããforall a. a
ã¯ãåå¤æ° a
ã«ããã¹ã¦ã®åã«å¯¾å¿ãããã¨ããæå³ãæããã¦ãã¾ãã*1
ãã®ããã«ãå ¨ç§°éååã§åå¤æ°ãéåããï¼éçãªæå³ãæãããï¼ãã¨ããå ¨ç§°éåï¼Universal Quantificationï¼ã¨å¼ã³ã¾ãã*2
ããã¦ãé常ã¯ç¹ã«æ示ããªãã¦ãæé»çã« forall
ãä»ä¸ãããã®ã§ã以ä¸ã¯ããããåãæå³ã«ãªãã¾ãã
{-# LANGUAGE ExplicitForAll #-} {-- ããããä¸ããé çªã« - forallãçç¥ - forallãæ示 - forallã修飾ããç¯å²ãåãããããããããæ¬å¼§ãè¨è¿° --} id :: a -> a id :: forall a. a -> a id :: forall a. (a -> a) reverse :: [a] -> [a] reverse :: forall a. [a] -> [a] reverse :: forall a. ([a] -> [a]) map :: (a -> b) -> [a] -> [b] map :: forall a b. (a -> b) -> [a] -> [b] map :: forall a b. ((a -> b) -> [a] -> [b])
ä¸è¨ã®ã³ã¼ãã§åãããã¨ã¯ãæé»çã«ä»ä¸ããã forall
ã¯ãé¢æ°ã®æãå¤å´ã«ç½®ãããé¢æ°å
¨ä½ã修飾ããã¨ãããã¨ã§ããæ¬å¼§ã®ä¸ãªã©ãé¢æ°ã®å
å´ã«ã¯ç½®ããã¾ããã
ãã¦ãå
¨ç§°éåã«ã¤ãã¦èª¬æãã¾ããããçµå±ã®ã¨ããforall
ãçç¥ãã¦ãããªãã¦ãåãæå³ã«ãªãã®ã§ãforall
ã®å½¹å²ãã¾ã æ¼ ç¶ã¨ãã¦ãã¾ãã
ããã§ã¯ãforall
ã®å½¹å²ãæ´ã«æ¢ãããã次ã¯ã©ã³ã¯Nå¤ç¸ã¸ã¨é²ã¿ã¾ãããã
éååãé¢æ°ã®å å´ã§å®ç¾©ãã
è¨èªæ¡å¼µã® RankNTypes
ï¼ã©ã³ã¯Nå¤ç¸ï¼ã使ç¨ããã¨ãå
¨ç§°éåå forall
ãé¢æ°ã®å
å´ã§æ示çã«å®ç¾©ãããã¨ãã§ãã¾ããããã«ããã修飾ããåå¤æ°ã®ã¹ã³ã¼ããéå®çã«ããã¨ã¨ãã«ãåæ¨è«ã®å¶éãç·©åããããã¨ãã§ãã¾ããã©ã³ã¯Nå¤ç¸ã®è©³ç´°ã¯å¾è¿°ããã¨ãã¦ããããä½ãæå³ããã®ãé ã追ã£ã¦èª¬æãã¾ãã
以ä¸ã®é¢æ° applyTrue
ã¯ãå¼æ°ã§åãåã£ãé¢æ° a -> a
ã« True
ãè¨å®ãããã®çµæã Bool
ã¨ãã¦è¿ãé¢æ°ã§ãã
{-# LANGUAGE ExplicitForAll #-} applyTrue :: forall a. (a -> a) -> Bool applyTrue f = f True
ããã¯åæ¤æ»ã§å¤±æãã¦ãã¾ãã¾ãã
⢠Couldn't match expected type âaâ with actual type âBoolâ âaâ is a rigid type variable bound by the type signature for: applyTrue :: forall a. (a -> a) -> Bool at...
ãªããªããapplyTrue
ã¨é¢æ° a -> a
ã¨ã®éã§ãä¸è¨ã®éãæå¾
ããåã¨å®éã®åãä¸è´ãã¦ããªãããã§ããï¼ãã詳ãã解説ã¯å¾ã»ã©ï¼
- é¢æ°
a -> a
ã¯å¼æ°ã«a
ãæå¾ ãã¦ãã®ã«Bool
ã渡ãã¦ãã applyTrue
ã®çµæåã¯Bool
ãæå¾ ãã¦ããã®ã«é¢æ°a -> a
ã¯a
ãè¿ãã¦ãã
ãã®ãããªå ´åã¯ãè¨èªæ¡å¼µã® RankNTypes
ã使ç¨ãã¦ãå
¨ç§°éåå forall
ãé¢æ°ã®å
å´ã§æ示ãããã¨ã§ãåæ¨è«ã®å¶éãç·©åããã¾ãã
{-# LANGUAGE RankNTypes #-} -- forallãæ¬å¼§ã®ä¸ã«å ¥ãã applyTrue :: (forall a. a -> a) -> Bool applyTrue f = f True
ããã¯åæ¤æ»ã«æåãã¾ãã
forall a. (a -> a)
ã (forall a. a -> a)
ã¨ããã ãã§ãããapplyTrue
ã¨é¢æ° forall a. a -> a
ã¨ã®éã§ãæå¾
ããåã¨å®éã®åãä¸è´ããããã§ãã
ãªããã®ãããªãã¨ãå®ç¾ã§ããã®ããã©ã³ã¯Nå¤ç¸ã«ã¤ãã¦ãã£ã¨èª¿ã¹ã¦ã¿ãå¿ è¦ãããã¾ããã
ã©ã³ã¯Nå¤ç¸ã®æ¦è¦ã¨ç¹å¾´
ã©ã³ã¯Nå¤ç¸ã®æ¦è¦
ã©ã³ã¯Nå¤ç¸ï¼Higher-rank polymorphismï¼*3 ã®ãã©ã³ã¯ãã¨ã¯ãé¢æ°ã®å¤ç¸æ§ã®æ·±ãï¼forall
ã修飾ããé¢æ°ã®ç¢å° ->
ã®æ·±ãï¼ã表ãã¦ãããã©ã®ãããæ·±ããã§ã©ã³ã¯ã®Nã決ã¾ãã¾ãã
å ·ä½ä¾ãè¦ã¦ã¿ã¾ãããã以ä¸ã¯ãä¸ã«è¡ãã»ã©ä¸ä½ã®ã©ã³ã¯ã«ãªãã¾ããï¼ã©ã³ã¯ãé«ããªãã¨é¢æ°ã®å¤ç¸æ§ã¯æ·±ããªãã¾ãï¼
t -- ã©ã³ã¯0åç¸ forall a. a -> t -- ã©ã³ã¯1å¤ç¸ (forall a. a -> t) -> t -- ã©ã³ã¯2å¤ç¸ ((forall a. a -> t) -> t) -> t -- ã©ã³ã¯3å¤ç¸
ããã§ããã¨ãå
ã»ã©ã® applyTrue
ã¯ãããªãã¾ããã*4
applyTrue :: forall a. (a -> a) -> Bool
ã¯ã©ã³ã¯1å¤ç¸applyTrue :: (forall a. a -> a) -> Bool
ã¯ã©ã³ã¯2å¤ç¸
ã§ã¯ãã©ã³ã¯ãé«ããªãã¨ã©ã®ãããªãã¨ãèµ·ããã®ã§ããããã以ä¸ã¯ãã©ã³ã¯Nå¤ç¸ããããã2ã¤ã®ç¹å¾´ãã¾ã¨ãã¦ã¿ã¾ããã
- ä¸ä½ã®ã©ã³ã¯ã®åã¯ãä¸ä½ã®ã©ã³ã¯ãã決å®ãããã¨ãã§ããªãã®ã§ãåã®æ±ºå®ãå éãã«ã§ããï¼åæ¨è«ã®å¶éãç·©åï¼
- éåãããåã¯ã修飾ããã¹ã³ã¼ãããå¤ã«åºãããªãï¼ã¹ã³ã¼ãå ã§ã®åã®æç¸ï¼
ç¹å¾´ãã®1: åæ¨è«ã®å¶éãç·©å
ã¾ã1ã¤ç®ã®ç¹å¾´ã«ã¤ãã¦ã
ä¸ä½ã®ã©ã³ã¯ã®åã¯ãä¸ä½ã®ã©ã³ã¯ãã決å®ãããã¨ãã§ããªãã®ã§ãåã®æ±ºå®ãå éãã«ã§ããï¼åæ¨è«ã®å¶éãç·©åï¼
å
ã»ã©ã®é¢æ° applyTrue
ã§èª¬æãã¾ãã
æåã«åæ¤æ»ã§å¤±æããã¨ãã¯ãapplyTrue
ã¯ã©ã³ã¯1å¤ç¸ã§ããã
{-# LANGUAGE ExplicitForAll #-} applyTrue :: forall a. (a -> a) -> Bool applyTrue f = f True
å®ã¯ forall
ãé¢æ°ã®æãå¤å´ã«ããå ´åãåã®æ¨è«ã¯é¢æ°ã®å¼ã³åºãå
ã®è²¬åã«ãªãã¾ããapplyTrue
ã®å ´åã¯ãå¼ã³åºãå
ãåãæ¨è«ãã¦ãã¾ãã®ã§ãé¢æ° a -> a
ã¯ã©ã³ã¯0åç¸ã¨ãã¦æ±ãããä¸ååãªå¤ç¸æ§ã®ã¾ã¾ Bool
ã®å¤ãé©ç¨ããã®ã§ã¨ã©ã¼ã«ãªã£ãã®ã§ããã
åæ¤æ»ã«å¤±æããã¨ãã®ã¨ã©ã¼ã¡ãã»ã¼ã¸ã¯ãa
㯠Bool
ãã©ããåãããªãåã«æ±ºå®ããã¦ããã®ã§ãåãä¸è´ããªããã¨è¨ã£ã¦ããããã§ããã
⢠Couldn't match expected type âaâ with actual type âBoolâ âaâ is a rigid type variable bound by the type signature for: applyTrue :: forall a. (a -> a) -> Bool at...
ãã®å¾ãapplyTrue
ãã©ã³ã¯2å¤ç¸ã¸ä¸ãããã¨ã§ãapplyTrue
ã¯å¼ã³åºãå
ããè¦ã¦ä¸ä½ã®ã©ã³ã¯ã§ãããã¨ããé¢ä¿ã«ããã®ãããã§ããã
{-# LANGUAGE RankNTypes #-} applyTrue :: (forall a. a -> a) -> Bool applyTrue f = f True
åè¿°ã®éããä¸ä½ã®ã©ã³ã¯ã®åã¯ä¸ä½ã®ã©ã³ã¯ãã決å®ãããã¨ãã§ããªãã®ã§ãé¢æ°ã®å¼ã³åºãå ã¯åã®æ¨è«ãå éãã«ãã¾ããã¤ã¾ããåæ¨è«ã®è²¬åã¯é¢æ°ã®å¼ã³åºãå ã«å¤ãã£ãã®ã§ãã
ã§ã¯ãå éãã«ãããåã®æ¨è«ã¯ã©ã®æç¹ã§è¡ããåã決å®ããã®ããå®ã¯ãé«ã©ã³ã¯ãªå¤ç¸åã®å ´åãåãæ示ããªãéã決å®ã§ãã¾ãããæ示ããªããã°åæ¤æ»ã§å¤±æãã¾ãã
applyTrue
ã®å ´åã¯ãé¢æ°å
é¨ã§é¢æ° forall a. a -> a
ã« Bool
ã®å¤ã渡ããã®ã§ããã®æç¹ã§ãããã a
㯠Bool
ã§ããã¨æ¨è«ããã¾ããããã®çµæãapplyTrue
ã¨é¢æ° forall a. a -> a
ã¨ã®éã§ãæå¾
ããåã¨å®éã®åãä¸è´ããã®ã§ãã
åã®æ±ºå®ãå éãã«ããã¨ãããªãã¨ãã§ããããã¨ããä¾ãããä¸ã¤ã
以ä¸ã®é¢æ° applyTuple
ã¯ãããããç°ãªãåã®è¦ç´ ãæã¤ã¿ãã« (True, 'a')
ã«å¼æ°ã§åãåã£ãé¢æ° forall a. a -> a
ãé©ç¨ããé¢æ°ã§ãã
{-# LANGUAGE RankNTypes #-} applyTuple :: (forall a. a -> a) -> (Bool, Char) applyTuple f = (f True, f 'a')
applyTrue
ã®ã¨ãã¨åãããã«ãapplyTuple
ãå¼ã³åºãããæç¹ã§ã¯é¢æ° forall a. a -> a
ã®åã®æ¨è«ã¯å
éãã«ããã¦ãã¾ããé¢ç½ãã®ããå
éãã«ãããåã®æ¨è«ã¯ãã¿ãã«ã®ããããç°ãªãåã®è¦ç´ ã«é¢æ°ãé©ç¨ããéãããããã®åã¨ãã¦æ¨è«ã§ããã®ã§ãã
ç¹å¾´ãã®2: ã¹ã³ã¼ãå ã§ã®åã®æç¸
次ã«ã2ã¤ç®ã®ç¹å¾´ã«ã¤ãã¦ã§ãã
éåãããåã¯ã修飾ããã¹ã³ã¼ãããå¤ã«åºãããªãï¼ã¹ã³ã¼ãå ã§ã®åã®æç¸ï¼
ä¾ãã°ã©ã³ã¯2å¤ç¸ã® (forall a. a -> a)
ã¯ãæ¬å¼§ã®ä¸ã¨ããéå®ãããã¹ã³ã¼ãã«å¯¾ãã¦åå¤æ° a
ãéåãã¦ãã¾ãããã®ãããªé«ã©ã³ã¯ã®åã¯ã修飾ããã¹ã³ã¼ãã®ä¸ã§æç¸ãããã®ã§ãå¤ã¸æã¡åºããã¨ãã§ãã¾ããã
ã¤ã¾ãããããããã¨ã¯ã§ãã¾ããã
(forall a. a -> a) -> a
ããããã¹ã³ã¼ãã®ä¸ã¨å¤ã¨ã§ã¯ã©ã³ã¯ãéãã®ã§ãa
ã¯ã¹ã³ã¼ãã®å¤ã§ã¯åå¨ã§ããªãã®ã§ããããã¦ããã®ãããªã¹ã³ã¼ãã«æç¸ãããåã¯ãã¹ã³ã¼ã¬ã å®æ°ï¼skolem constantsï¼ã¨å¼ã°ãã¦ãã¾ãã
forallã®æ¢æ±ã¯ããã§çµãã
ããã¾ã§ã®forallã®æ¢æ±ã§ãSTã¢ããã®ããªãã¯ã解ãæããããã®æºåãæ´ãã¾ããã*5
次ã¯ãããããSTã¢ããã¯ãªãå¤æ´å¯è½ãªåç §ãå¤ã¸æã¡åºããªãã®ãã解ãæããã¦ããã¾ãã
STã¢ããã®ããªãã¯
ããã§ã¯ãå ã»ã©ã®STã¢ããããå¤æ´å¯è½ãªåç §ãå¤ã¸æã¡åºããã¨ããã³ã¼ããããä¸åº¦è¦ã¦ã¿ã¾ããããããããèªã¿è§£ãã¦ããã¾ãã
runST $ newSTRef 100
newSTRefã®çµæåã®æå³
ã¾ãã¯ãnewSTRef
ã®é¨åã§ããã·ã°ããã£ã¯ããã§ãããã
newSTRef :: a -> ST s (STRef s a)
ST s a
ã® a
ã¯å¤ã表ãã¦ããã®ã§ãnewSTRef
ã®çµæå ST s (STRef s a)
ã§å¤ã表ãã¦ããã®ã¯ãåç
§åã® (STRef s a)
ã¨ãããã¨ã«ãªãã¾ãã
ããã¨ã¹ã¬ããã表ã s
ã§ãããå°ãåã«ãã® s
ã ST
㨠STRef
ã®ä¸¡æ¹ã«ããã®ãå¤ã ã¨æ¸ãã¾ãããããã¯ãST
ã® s
ãåç
§å STRef
ã«ã¿ã°ä»ããããã¨ã§ãSTRef
ã ST
ã® s
ã«ä¾åããã¨ããé¢ä¿ãä½ãåºãã¦ããã®ã§ãã
åå¤æ° s
ã®ããä¸ã¤æ³¨ç®ãã¹ãç¹ã¯ãåãæ¨è«ããæ
å ±ãä½ãç¡ãã®ã§å¤ç¸åãç¶æãã¦ããã¨ãããã¨ã§ããå
ã»ã©ã® newSTRef 100
ã¯ã
GHCi> x = 100 :: Int GHCi> :t newSTRef x newSTRef x :: ST s (STRef s Int)
㨠s
ã¯å¤ç¸åãç¶æããã¾ã¾ã«ãªã£ã¦ãã¾ãã
runSTã®å¼æ°ã®åã®æå³
次㫠runST
ã®ã·ã°ããã£ãè¦ã¦ã¿ã¾ãããã
runST :: (forall s. ST s a) -> a
runST
ã¯ã(forall s. ST s a) -> a
ã¨ã©ã³ã¯2å¤ç¸ã§ãST s a
ã® s
ã ããéå®ãããã¹ã³ã¼ãå
ã§éåããã¦ãã¾ãããã®ãããå¤ã® a
ã¯ã¹ã³ã¼ãã®å¤ã¸æã¡åºããã¨ãã§ãã¾ãããs
ã¯ã¹ã³ã¼ãå
ã§æç¸ãããã¹ã³ã¼ã¬ã å®æ°ãªã®ã§å¤ã¸æã¡åºããã¨ãã§ãã¾ããã
ããã§çåã§ããã·ã°ããã£ãèªã¿è§£ãéã ST s a
ã® a
ã¯ã¹ã³ã¼ãã®å¤ã¸æã¡åºããã¯ããªã®ã«ããªãããã¯å¤±æããã®ã§ããããï¼
runST $ newSTRef 100
å®ã¯ããã§ãnewSTRef
ã®çµæå ST s (STRef s a)
ã®ã³ã¬ãå¹ãã¦ããã®ã§ãã
STRef
ã¯ST
ã®s
ã«ä¾åãã¦ããs
ã¯å¤ç¸åãç¶æããã¾ã¾ã«ãªã£ã¦ãã
ã¤ã¾ã STRef
ã¯ãã¹ã³ã¼ã¬ã å®æ°ã§åãæ¨è«ããããã®æ³¨éãä½ããªã s
ã«ä¾åãã¦ããã®ã§ãs
ã«æç¸ãããå½¢ã§ã¹ã³ã¼ãã®å¤ã¸æã¡åºããã¨ãã§ããªãã®ã§ãã
以ä¸ããSTã¢ããã¯ãªãå¤æ´å¯è½ãªåç §ãå¤ã¸æã¡åºããªãã®ãã®çç±ã«ãªãã¾ãã
ãããã«
æå¾ã¾ã§èªãã§ããã ãã¦ãããã¨ããããã¾ããï¼
ä»åã®STã¢ããã¯ãHaskellå ¥é é¢æ°åããã°ã©ãã³ã°è¨èªã®åºç¤ã¨å®è·µ ã®è注ã§ãSTã¢ããã¯ãGHCã®RankNTypesã¨ããæ¡å¼µã使ã£ã¦ãã¦â¦ãã¨æ¸ããã¦ãã¦ãããï¼ããã£ã¦ã©ããããã¨ï¼ãã¨ããã¨ããããè²ã ãªè¨äºãæ¸ç±ãèªãã§ãèªåãªãã«ç解ã§ãããã¨ãã¾ã¨ãã¦ã¿ã¾ããã
Haskellã®åã·ã¹ãã ã®ä¸çã«é äºããä»å¹´5æã«æ¬æ ¼çã«å ¥éãã¾ããããæ¢æ±ããã°ããã»ã©æ¿åãªä¸çãåºãã£ã¦è¡ã£ã¦æ¥½ããã§ãããä»å¾ãæ¢æ±ãç¶ãããã¨æãã¾ãï¼
è¨æ£å 容ï¼2019/12/06ï¼
以ä¸ã®ç¹ã§æ£ç¢ºãã«æ¬ ãã¦ããã®ã§è¨äºã®ä¸é¨ãè¨æ£ãã¾ããã
ãéååãé¢æ°ã®å å´ã§å®ç¾©ãããã«ã¦ãã¿ãã«ã®ããããã®è¦ç´ ã«å¤ç¸åé¢æ°ãé©ç¨ããä¾ãæãã¾ããã
{-# LANGUAGE ExplicitForAll #-} applyTuple :: forall a. (a -> a) -> (Bool, Char) applyTuple f = (f True, f 'a')
ããã«å¯¾ãã¦ããã©ã¡ããä¸æ¹ã®åã¨ãã¦æ¨è«ããã¦ãã¾ãã両æ¹ã®åã«å¯¾å¿ã§ããªããã¨è§£èª¬ãã¾ãããå®ã¯ããã§ã¯ãªãã¦ãé¢æ° a -> a
ã®å㯠applyTuple
ã®å¼ã³åºãå
ãæ¨è«ãã¦ãã¾ãã®ã§ãé¢æ° a -> a
ã¯ã©ã³ã¯0åç¸ã¨ãã¦æ±ãããä¸ååãªå¤ç¸æ§ã®ã¾ã¾ã¿ãã«ã®åè¦ç´ ã«é©ç¨ããããã¨ã©ã¼ã«ãªã£ãã®ã§ããã
ããã¯åä¸ã®åã§ãã¨ã©ã¼ã«ãªãã¾ãã
{-# LANGUAGE ExplicitForAll #-} applyTrue :: forall a. (a -> a) -> Bool applyTrue f = f True
ãã®åã®æ¨è«ã®å¶éãç·©åããå¼ã³åºãããå´ã§åã®æ¨è«ããããã®ããã©ã³ã¯Nå¤ç¸ã¨ããããã§ãã
ä¸è¨ã®ç¹ãããã¨è注ã®Rank2Typesã«ã¤ãã¦ãå çä¿®æ£ãã¦ãã¾ãã
@Mizunashi_Manaããããææãããã¨ããããã¾ããï¼
https://twitter.com/Mizunashi_Mana/status/1201886227797950464
åèè³æ
- Thinking with Types
- Haskell Wiki: Monad/ST
- Hackage: Control.Monad.ST
- GHC User's Guide: 9.21. Arbitrary-rank polymorphism
- Wikibooks: Haskell/Polymorphism
- Wikibooks: Haskell/åå¨éåãããå
- What I Wish I Knew When Learning Haskell: Quantification [æ¥æ¬èªè¨³]
- 第20åãæ´æ°ãé«éåããããã®STã¢ãã
*1:åè: å ¨ç§°è¨å·ï¼Wikipediaï¼
*2:åè: éåï¼Wikipediaï¼
*3:ãä»»æã©ã³ã¯å¤ç¸ï¼Arbitrary-rank polymorphismï¼ãã¨è¡¨è¨ããããã¨ãããã¾ãã
*4:ä¸è¬çã«ã©ã³ã¯2以ä¸ã¯ã©ã³ã¯Nã¨ãã¦è¡¨ããã¨ãå¤ããããªã®ã§è¨èªæ¡å¼µã¯ RankNTypes ã使ç¨ãã¾ããããã©ã³ã¯2ç¨ã® Rank2Types ã¨ããã®ãããã¾ãã Rank2Typesã¯RankNTypesã®ã¨ã¤ãªã¢ã¹ã§ãæ´å²ççµç·¯ã¨äºææ§ã®ããã«æ®ããã¦ããéæ¨å¥¨ã®è¨èªæ¡å¼µãªã®ã§ããã¡ãã®èª¬æã¯ç¡è¦ãã¦ãã ãããï¼åèï¼
*5:éåãã¹ã³ã¼ã¬ã ã¯è¿°èªè«çã®æ¦å¿µã§ãããæ®å¿µãªããç§ã¯è¿°èªè«çãåãã£ã¦ãªãã®ã§ãã以ä¸è©³ãã説æã¯ã§ããªãã®ã§ãã