39953


次のコードにおいて型検査時に、`go = readArray array` で、その次の行のコメントのようなエラーが出ました。  
エラーの原因としては、2つの `ST` の（片方は `STArray` ですが）内部状態の `s` と `s1`
が別物だと認識されていることと考えています。  
この `s` と `s1` が同じであると明記することはできますか？  
または、この形式だと根本的に `s` と `s1` は別物になるべきでしょうか？

ちなみに `go` のシグネチャを変更したコメントアウトした版にすると `s` が同じことが明記できるので型検査が通ります。

[code]

    #!/usr/bin/env stack
    -- stack --resolver lts-9.14 --install-ghc runghc --package array
    
    import Control.Monad.ST
    import Data.Array.ST
    
    main = print $ runST $ do
        array <- newArray (0, 1 :: Int) (0 :: Int) :: ST s (STArray s Int Int)
        let
            go :: Int -> ST s Int
            go = readArray array
    -- starray.hs:11:14: error:
    --   • No instance for (MArray (STArray s) Int (ST s1))
    --     arising from a use of ‘readArray
            -- go :: STArray s Int Int -> Int -> ST s Int
            -- go = readArray
        writeArray array 1 1
        go 1
        -- go array 1
    
[/code]


CC BY-SA 3.0
2017-11-30T09:44:09.037
39952
2017-11-30T10:17:25.697
153
question
haskell
2つの ST s の s が同じであることを明示する方法はありますか？


(詳しい人曰く) `ScopedTypeVariables` 言語拡張を使うと良いそうです。  
以下のコードで `stack runghc` したら `1` と返ってきましたよ。

[code]

    {-# LANGUAGE ScopedTypeVariables #-}
    
    module Main where
    
    import Control.Monad.ST
    import Data.Array.ST
    
    main :: IO ()
    main = print $ runST st
    
    st :: forall s . ST s Int
    st = do
      array <- newArray (0, 1) 0 :: ST s (STArray s Int Int)
      let
          go :: Int -> ST s Int
          go = readArray array
      writeArray array 1 1
      go 1
    
[/code]


CC BY-SA 3.0
2017-11-30T10:17:25.697
39953
2017-11-30T10:17:25.697
24425
39952
answer