왜 map, fmap 및 liftM이 있습니까?


102
map :: (a -> b) -> [a] -> [b]

fmap :: Functor f => (a -> b) -> f a -> f b

liftM :: Monad m => (a -> b) -> m a -> m b

기본적으로 동일한 작업을 수행하는 세 가지 다른 기능이있는 이유는 무엇입니까?


32
대부분의 역사. fmap은 교육적인 이유로 map과 구별되며, liftM은 역사적인 이유로 fmap과 구별됩니다 (즉 Functor는 Monad의 수퍼 클래스가
아님

12
아, 그리고 명확하게하기 위해서 : 그들은 "본질적으로"같은 일을하지 않습니다. 모두 mapliftM가장 확실하게해야 정확히 같은 일을 fmap.
CA McCann 2011 년

2
fmap그리고 liftM정확히 똑같은 일을 하는 동안 , map물론 그것들은 특별한 경우에 불과합니다. fmap id getLine잘 입력 된 반면 map id getLine그렇지 않습니다.
Thorsten

답변:


91

map목록에 대한 작업을 단순화하고 역사적인 이유로 존재합니다 (fmap이있을 때 Haskell에서지도의 요점무엇입니까? 참조 ).

별도의지도 기능이 필요한 이유를 물어볼 수 있습니다. 현재 목록 전용 맵 기능을 없애고 대신 fmap의 이름을 map으로 변경하지 않는 이유는 무엇입니까? 음, 좋은 질문입니다. 일반적인 주장은 방금 Haskell을 배우는 사람이 맵을 잘못 사용할 때 Functor에 대한 것보다 목록에 대한 오류를 보는 것이 훨씬 더 많다는 것입니다.

- Typeclassopedia , 페이지 20

fmap그리고 liftM모나드가 자동으로 하스켈에서 펑하지 않았기 때문에 존재한다 :

우리가 fmap과 liftM을 모두 가지고 있다는 사실은 수학적으로 말하면 모든 모나드는 functor이지만 Monad 유형 클래스에 Functor 인스턴스가 필요하지 않다는 사실의 불행한 결과입니다. 그러나 fmap과 liftM은 본질적으로 상호 교환이 가능합니다. 왜냐하면 어떤 유형이든 Functor의 인스턴스가되지 않고 모나드의 인스턴스가되는 것은 (기술적 인 의미가 아니라 사회적 의미에서) 버그이기 때문입니다.

- Typeclassopedia , 페이지 33

편집 : agustuss의 역사 mapfmap:

그것은 실제로 일어나는 방식이 아닙니다. 무슨 일이 있었는지 맵의 유형이 Haskell 1.3의 Functor를 포함하도록 일반화되었습니다. 즉, Haskell 1.3에서는 fmap을 map이라고했습니다. 이 변경 사항은 Haskell 1.4에서 되돌려졌으며 fmap이 도입되었습니다. 이러한 변화의 이유는 교육적이었습니다. 초보자에게 하스켈을 가르 칠 때 매우 일반적인 유형의지도는 오류 메시지를 이해하기 더 어렵게 만들었습니다. 제 생각에는 이것은 문제를 해결하는 올바른 방법이 아닙니다.

- fmap 함수가있을 때 하스켈 맵의 포인트는 무엇입니까?


13
그리고 @augustss가 설명하는 변경 사항이 적용된 후 10 년 이상 하스켈을 처음 접한 사람으로서 현재 언어를 배우고있는 사람들을 돕는 데 많은 시간을 보냈습니다. 어쨌든. 쓸모없는 중복을 상쇄하기에 충분하지 않습니다 (이와 같은 질문을하는 사람들로 이어집니다). Functor클래스는 무시하기에 너무 일반적이고, 초보자는 종종 어쨌든 오류 메시지에 의해 혼란스러워!
CA McCann 2011 년

10
그냥 제거하면 안되나요 liftM? 코드를 깨 뜨리십시오. 코드가 github에서 수정되고 해킹에 업로드되는 데 보통 2 일 미만이 걸립니다. 아니면 내가 거칠고 미쳤나요?
Tarrasch

1
@Tarrasch : 모든 사람의 사용은 모든 패키지는 시간에서 업데이트에 대한 좋은 트랙 기록을 가지고, GitHub에, 나는 하나는 사용하는 경향이 위해 liftM할 - 블록 동안보다는 fmap내가 사용할 때 더 나은에 맞는 때문에 함께 liftM2등, 게다가.
ivanm

1
@ L01man 사람들이이 작업을했습니다. stackoverflow.com/questions/5730270/…을 참조 하고 적어도 숫자 클래스의 경우 대안이 있습니다. hackage.haskell.org/packages/archive/numeric-prelude/0.3.0.2/…
li.davidm

1
@ L01man 네, 곧 수정 될 것입니다. 실용적 모나드 제안 은 하스켈의 다음 버전에 전달합니다 같은 (AMP)을 보인다. GHC 7.8.3 에는 --fwarn-amp전환을 위해 기존 코드를 업데이트하는 데 도움 이되는 새 플래그 가 있습니다.
recursion.ninja
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.