2012-08-07 3 views
21

동시성 라이브러리 GHC.Conc에는 numCapabilities이라는 함수가 있습니다. 유형은 numCapabilities :: Int이며 명령 줄 플래그로 전달한 숫자가 실제로 반환됩니다 (예 : +RTS -N 5 인 경우 5).numCapabilities가 왜 순수 함수입니까?

그러나 getArgs (유형 : IO [String])은 본질적으로 동일하지만 (해석되지 않은 비 런타임 인수를 반환 함) 순수 함수는 아닙니다.

순수한 코드에 numCapabilities이 자주 필요한 경우 다른 명령 줄 옵션 인 이 아닌 순수 코드에이 필요합니까?

누락되었거나 numCapabilities 디자인 결함이 있습니까? 아니면 다음 몬스터를 쓸 수 있습니까?

myGetArgs = unsafePerformIO getArgs 
+6

이제 반대의 이유가 있습니다. 프로그램 실행 중에 getArgs의 값이 절대로 바뀌지 않기 때문에 왜 I/O가 필요한지 /해야하는지 정확히 알 수 없습니다. – sepp2k

+4

답변 중 하나에서 언급했듯이, _pure_ 표현식을 정의하는 방법에 따라 다릅니다. 표현식 자체가 무엇이든 의존하지 않는다면 표현식을 _pure_로 정의 할 수 있습니다. 이 정의에 따르면'numCapabilities'는 순수하지 않으므로 'Int'유형을 갖는 것은 설계 결함으로 간주되어야합니다. Conal Elliott의 블로그 게시물 [Haskell의 순결 개념] (http://conal.net/blog/posts/notions-of-purity-in-haskell)에 관심이있을 수 있습니다. –

+0

'numCapabilities'는'-N'에 주어진 값을 반환 할 필요가 없습니다. 단지'getNumCapabilities'를 호출하기 때문에, 그때 그때의 많은 능력을 돌려줍니다. 이 문제는 버그라고 생각합니다.하지만 GHC 모듈에서 무엇을 의지 할 수 있는지 보장하기 란 어렵습니다. –

답변

21

나는 이와 같은 상황에서해야 할 일에 대해 매우 다양한 견해를 보았습니다. 어떤 사람들은 사이에서 달라질 수있는 값은이 순수하지 않아야한다고 생각하며, 프로그램의 로컬 런타임 (예 : 일부 "구성"이 "설정"된 후)에서 값이 변경되지 않는 한, main), 그것은 순수해야합니다.

base 패키지는 중간 정도에 자리 잡고있는 것으로 보입니다. numCapabilities은 (실행하는 동안 내가 알고있는 한)이 아니지만 getArgs 일 수 있습니다.

getArgs을 통해받은 args가 변경되는 withArgs 함수가 있기 때문입니다. 그래서, 그 대답.

+1

['setNumCapabilities'] (http : // www .haskell.org/ghc/docs/latest/html/libraries/base/GHC-Conc.html # v : setNumCapabilities)? –

+9

'numCapabilities'는 매개 변수를'-N #'으로 반환하고,'getNumCapabilities'는 실제로 얼마나 많은 능력이 있는지를 반환합니다. 'setNumCapabilities'는'getNumCapabilities'에 의해 얻어지는 실제 숫자를 변경합니다. 'get *'과'set *'함수는 모두'IO' 모나드에 있습니다. – dflemstr

+0

그 이유는'numCapabilities'와'getNumCapabilities' 둘 다 왜'args'와'getArgs' 둘 다가 아니라는 것입니다. – helami

3

나는 그것이 실수라고 말하고 싶지만, 순결이 무엇인지에 달려있다. 게시물 Notions of purity in Haskell 및 해당 토론을 참조하십시오. 간단히 말해서, 게시물의 논점은 타입이 의미를 가지며, Int의 의미에 numCapabilities과 같은 것을위한 공간이 없다는 것입니다. 이것은 실행 문맥 의존적입니다.

15

친애하는.

numCapabilities :: Int 
numCapabilities = unsafePerformIO $ getNumCapabilities 

다음과 같은 ghci 세션 문제 설명 : - numCapabilities의 값

[[email protected] ~]$ ghci 
GHCi, version 7.4.2: http://www.haskell.org/ghc/ :? for help 
Loading [...] 
ghci> :m +GHC.Conc 
ghci> numCapabilities 
1 
ghci> setNumCapabilities 2 
ghci> numCapabilities 
1 
ghci> :q 
Leaving GHCi. 

[[email protected] ~]$ ghci 
GHCi, version 7.4.2: http://www.haskell.org/ghc/ :? for help 
Loading [...] 
ghci> :m +GHC.Conc 
ghci> setNumCapabilities 2 
ghci> numCapabilities 
2 

확실히 나쁜 당신이 numCapabilities의 정의를 보면, 당신은 그냥 볼 수 있습니다 프로그램에있을 수있는 setNumCapabilities 호출과 관련하여 평가 시점에 따라 달라집니다. 첫 번째 세션에서는 IO이 처음 평가 될 때만 실행되므로 numCapabilities은 일관성을 유지합니다. 그러나 인라인이있는 경우 (이름에 NOINLINE 또는 기타로 표시되지 않음) 사실이 아닐지라도 - 원칙적으로 두 번 발생하는 두 가지 값 (numCapabilities)을 얻을 수 있습니다 (실제로는 만들지 못했지만 이것은 일어난다).

그래서 대답은 numCapabilities 하지 순수 기능이지만, 잘못 unsafePerformIO의 악명 높은 뒷문으로 같은 표시되어 있다는 점이다.

0

numCapabilities의 경우 초기 값은 getNumCapabilities이며 RTS -N 플래그 인수가 있거나 없으므로 유형이 동일해야합니다.

컴퓨터 최대 숫자보다 큰 숫자로 시도해 보셨습니까? 동시 스레드?

$ ghci +RTS -N99 
GHCi, version 7.4.2: http://www.haskell.org/ghc/ :? for help 
Prelude> :m +GHC.Conc 
Prelude GHC.Conc> numCapabilities 
99 
Prelude GHC.Conc> getNumCapabilities 
99 !!! 
관련 문제