2010-06-27 2 views
23

1에서 MAGIC_NUMBER까지 숫자 목록을 가지고 있다고 가정 해 봅시다. 미리 선언 할 수있는 방법이 있습니까?마법의 숫자를 피하기 위해 상수를 어떻게 사용합니까?

+1

"선언 번호"란 무엇입니까? – ony

+0

당신이 분명히해야 할 매우 중요한 포인트 : 언제 마법의 번호를 알고 있습니까? 컴파일 시간에 그것을 안다면 척은 아래에서 올바른 대답을 가지고 있습니다. –

답변

13

당신이 "마법"숫자 대수 값을 렌더링하고 모든 계산에 대수 데이터를 사용하고 정말 "마법"경우 일부라는 이름의 값을 사용하거나 구축 할 수 있습니다 더 많은 :

class FlagsMask f where mask :: f -> Int 

data Magics = Alpha | Beta | Gamma 
    deriving (Enum, Read, Show, Eq, Ord) 

instance FlagsMask Magics where 
    mask m = 2^fromEnum m 

data PermsFlag = FlagRead | FlagWrite | FlagExec | FlagSuper 

-- [flagRead, flagWrite, flagExec] = [2^n | n <- [0..2]] 
(flagRead : flagWrite : flagExec : _) = [2^n | n <- [0..]] 
flagSuper = 16 

instance FlagsMask PermsFlag where 
    mask FlagRead = flagRead 
    mask FlagWrite = flagWrite 
    mask FlagExec = flagExec 
    mask FlagSuper = flagSuper 
*Main> map fromEnum [Alpha .. ] 
[0,1,2] 
it :: [Int] 
*Main> zip [Alpha .. ] [1..] 
[(Alpha,1),(Beta,2),(Gamma,3)] 
it :: [(Magics, Integer)] 

45

물론입니다. 사실, Haskell이 순전히 기능적이라는 점을 감안할 때, 상수를 정의하는 것이 아닌 상수를 정의하는 것이 훨씬 쉽습니다.

magicNumber = 42 

magicList = [1..magicNumber] 
35

척의 답변은 정확합니다. 두 번째 줄에서 magicNum 단지 f x = 'A'처럼, 모든 일치하는 패턴입니다 -

magicNum = 42 

f magicNum = 'A' 
f _ = 'B' 

당신이 기대하는 것이 아니다 : 당신이 알아야 할 하나 개의 함정이있다. f x | x == magicNum = 'A'을 사용하십시오.

+1

사실, 표준 연산자를 이런 식으로 다시 바인딩 할 수도 있습니다. 예를 들어,'f (==) a b = a == b' 함수를 정의한 다음'f div 8 4'를 호출하면 결과는 false가 아니라 2가됩니다. (물론 이것은 병적 인 일입니다.) – Chuck

관련 문제