diff --git a/ChangeLog.md b/ChangeLog.md
new file mode 100644
--- /dev/null
+++ b/ChangeLog.md
@@ -0,0 +1,15 @@
+# 0.3.0.0
+
+`languageForPath` is now `languagesForPath`, which returns multiple results in cases of ambiguity.
+
+# 0.2.0.0
+
+Fix bug where `Gemfile.lock` files were being recognized as Ruby.
+
+# 0.1.0.1
+
+Adds documentation.
+
+# 0.1.0.0
+
+Initial release.
diff --git a/lingo.cabal b/lingo.cabal
--- a/lingo.cabal
+++ b/lingo.cabal
@@ -1,7 +1,7 @@
 cabal-version:       2.4
 build-type:          Custom
 name:                lingo
-version:             0.2.0.0
+version:             0.3.0.0
 synopsis:            File extension based programming language detection
 description:         Lingo uses github/linguist's language registry to enable fast detection of a file path's programming langauge based on extension or filename.
 homepage:            https://github.com/tclem/lingo-haskell
@@ -12,7 +12,11 @@
 category:            Data
 extra-source-files:  README.md
                    , languages.yml
+                   , ChangeLog.md
 
+tested-with:         GHC == 8.6.5
+                     GHC == 8.8.1
+
 custom-setup
   setup-depends:       Cabal
                      , base
@@ -27,13 +31,13 @@
   exposed-modules: Data.Languages
   other-modules: Gen_Languages
   autogen-modules: Gen_Languages
-  build-depends:       base ^>=4.12.0.0
-                     , bytestring
-                     , containers
-                     , filepath
-                     , raw-strings-qq
-                     , text
-                     , yaml
+  build-depends:       base >= 4.12 && < 5
+                     , bytestring ^>= 0.10.8.2
+                     , containers ^>= 0.6.0.1
+                     , filepath ^>= 1.4.2.1
+                     , raw-strings-qq ^>= 1.1
+                     , text ^>= 1.2.3.1
+                     , yaml ^>= 0.11.1.2
   hs-source-dirs:      src
   default-language:    Haskell2010
   default-extensions:  OverloadedStrings
@@ -42,9 +46,9 @@
   type:                exitcode-stdio-1.0
   hs-source-dirs:      test
   main-is:             Spec.hs
-  build-depends:       base ^>=4.12.0.0
+  build-depends:       base
                      , lingo
-                     , hspec
+                     , hspec ^>= 2.7.1
   default-language:    Haskell2010
   default-extensions:  OverloadedStrings
 
diff --git a/src/Data/Languages.hs b/src/Data/Languages.hs
--- a/src/Data/Languages.hs
+++ b/src/Data/Languages.hs
@@ -2,7 +2,7 @@
 -- interacting with languages known to linguist
 -- (https://github.com/github/linguist).
 module Data.Languages
-  ( languageForPath
+  ( languagesForPath
   , languages
   , languagesByExtension
   , languagesByFileName
@@ -18,18 +18,16 @@
 import           Gen_Languages
 import           System.FilePath.Posix
 
--- | Find the Language (if any) for a FilePath.
-languageForPath :: FilePath -> Maybe Language
-languageForPath path = languageForFileName <|> languageForExtension
+-- | Find the set of possible languages for a given file path.
+--
+-- Multiple results will be returned for ambiguous files; for example, @.md@ files can be Markdown or GCC machine descriptions, and @.php@ files can be PHP or Hack source files.
+languagesForPath :: FilePath -> [Language]
+languagesForPath path = languageForFileName <|> languageForExtension
   where
     languageForFileName = languageFor (takeFileName path) languagesByFileName
     languageForExtension = languageFor (takeExtension path) languagesByExtension
-    languageFor k f = maybe Nothing lookupPrimary $ Map.lookup (Text.pack k) f
-
-    -- Some extensions and filenames associate with multiple languages, this is
-    -- a dumb way to specify which is the primary language.
-    lookupPrimary xs
-      | null xs = Nothing
-      | "Markdown" `elem` xs = lookup "Markdown"
-      | otherwise = lookup (head xs)
-      where lookup k = Map.lookup k languages
+    languageFor :: String -> Map.Map Text [LanguageKey] -> [Language]
+    languageFor k
+      = foldMap (maybeToList . flip Map.lookup languages)
+      . fromMaybe []
+      . Map.lookup (Text.pack k)
diff --git a/test/Spec.hs b/test/Spec.hs
--- a/test/Spec.hs
+++ b/test/Spec.hs
@@ -1,25 +1,29 @@
 module Main where
 
-import Test.Hspec
 import Data.Languages
+import Data.List (sort)
+import Test.Hspec
 
 main :: IO ()
 main = hspec $ do
   describe "detect language for path" $ do
     it "can detect Ruby by file extension" $
-      languageName <$> languageForPath "test.rb" `shouldBe` Just "Ruby"
+      languageName <$> languagesForPath "test.rb" `shouldBe` ["Ruby"]
 
     it "can detect Ruby by filename" $
-      languageName <$> languageForPath "Rakefile" `shouldBe` Just "Ruby"
+      languageName <$> languagesForPath "Rakefile" `shouldBe` ["Ruby"]
 
+    it "returns all languages that a PHP file could be" $
+      sort (languageName <$> languagesForPath "test.php") `shouldBe` ["Hack", "PHP"]
+
     it "Gemfile.lock is not Ruby" $
-      languageName <$> languageForPath "Gemfile.lock" `shouldBe` Nothing
+      languageName <$> languagesForPath "Gemfile.lock" `shouldBe` []
 
     it "returns Nothing for unknown files" $
-      languageName <$> languageForPath "noideawhatthisis" `shouldBe` Nothing
+      languageName <$> languagesForPath "noideawhatthisis" `shouldBe` []
 
     it "returns Nothing for unknown extensions" $
-      languageName <$> languageForPath ".noideawhatthisis" `shouldBe` Nothing
+      languageName <$> languagesForPath ".noideawhatthisis" `shouldBe` []
 
   describe "languages" $
     it "parsed languages.yml" $ do
